sde_rotator_r1.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "%s: " fmt, __func__
  6. #include <linux/platform_device.h>
  7. #include <linux/module.h>
  8. #include <linux/fs.h>
  9. #include <linux/file.h>
  10. #include <linux/delay.h>
  11. #include <linux/debugfs.h>
  12. #include <linux/interrupt.h>
  13. #include "sde_rotator_r1_hwio.h"
  14. #include "sde_rotator_core.h"
  15. #include "sde_rotator_util.h"
  16. #include "sde_rotator_r1_internal.h"
  17. #include "sde_rotator_r1.h"
  18. #include "sde_rotator_r1_debug.h"
  19. struct sde_mdp_hw_resource {
  20. struct sde_rot_hw_resource hw;
  21. struct sde_mdp_ctl *ctl;
  22. struct sde_mdp_mixer *mixer;
  23. struct sde_mdp_pipe *pipe;
  24. struct sde_mdp_writeback *wb;
  25. };
  26. struct sde_rotator_r1_data {
  27. struct sde_rot_mgr *mgr;
  28. int wb_id;
  29. int ctl_id;
  30. int irq_num;
  31. struct sde_mdp_hw_resource *mdp_hw;
  32. };
  33. static u32 sde_hw_rotator_input_pixfmts[] = {
  34. SDE_PIX_FMT_XRGB_8888,
  35. SDE_PIX_FMT_ARGB_8888,
  36. SDE_PIX_FMT_ABGR_8888,
  37. SDE_PIX_FMT_RGBA_8888,
  38. SDE_PIX_FMT_BGRA_8888,
  39. SDE_PIX_FMT_RGBX_8888,
  40. SDE_PIX_FMT_BGRX_8888,
  41. SDE_PIX_FMT_XBGR_8888,
  42. SDE_PIX_FMT_RGBA_5551,
  43. SDE_PIX_FMT_ARGB_1555,
  44. SDE_PIX_FMT_ABGR_1555,
  45. SDE_PIX_FMT_BGRA_5551,
  46. SDE_PIX_FMT_BGRX_5551,
  47. SDE_PIX_FMT_RGBX_5551,
  48. SDE_PIX_FMT_XBGR_1555,
  49. SDE_PIX_FMT_XRGB_1555,
  50. SDE_PIX_FMT_ARGB_4444,
  51. SDE_PIX_FMT_RGBA_4444,
  52. SDE_PIX_FMT_BGRA_4444,
  53. SDE_PIX_FMT_ABGR_4444,
  54. SDE_PIX_FMT_RGBX_4444,
  55. SDE_PIX_FMT_XRGB_4444,
  56. SDE_PIX_FMT_BGRX_4444,
  57. SDE_PIX_FMT_XBGR_4444,
  58. SDE_PIX_FMT_RGB_888,
  59. SDE_PIX_FMT_BGR_888,
  60. SDE_PIX_FMT_RGB_565,
  61. SDE_PIX_FMT_BGR_565,
  62. SDE_PIX_FMT_Y_CB_CR_H2V2,
  63. SDE_PIX_FMT_Y_CR_CB_H2V2,
  64. SDE_PIX_FMT_Y_CR_CB_GH2V2,
  65. SDE_PIX_FMT_Y_CBCR_H2V2,
  66. SDE_PIX_FMT_Y_CRCB_H2V2,
  67. SDE_PIX_FMT_Y_CBCR_H1V2,
  68. SDE_PIX_FMT_Y_CRCB_H1V2,
  69. SDE_PIX_FMT_Y_CBCR_H2V1,
  70. SDE_PIX_FMT_Y_CRCB_H2V1,
  71. SDE_PIX_FMT_YCBYCR_H2V1,
  72. SDE_PIX_FMT_Y_CBCR_H2V2_VENUS,
  73. SDE_PIX_FMT_Y_CRCB_H2V2_VENUS,
  74. SDE_PIX_FMT_RGBA_8888_UBWC,
  75. SDE_PIX_FMT_RGBX_8888_UBWC,
  76. SDE_PIX_FMT_RGB_565_UBWC,
  77. SDE_PIX_FMT_Y_CBCR_H2V2_UBWC,
  78. };
  79. static u32 sde_hw_rotator_output_pixfmts[] = {
  80. SDE_PIX_FMT_XRGB_8888,
  81. SDE_PIX_FMT_ARGB_8888,
  82. SDE_PIX_FMT_ABGR_8888,
  83. SDE_PIX_FMT_RGBA_8888,
  84. SDE_PIX_FMT_BGRA_8888,
  85. SDE_PIX_FMT_RGBX_8888,
  86. SDE_PIX_FMT_BGRX_8888,
  87. SDE_PIX_FMT_XBGR_8888,
  88. SDE_PIX_FMT_RGBA_5551,
  89. SDE_PIX_FMT_ARGB_1555,
  90. SDE_PIX_FMT_ABGR_1555,
  91. SDE_PIX_FMT_BGRA_5551,
  92. SDE_PIX_FMT_BGRX_5551,
  93. SDE_PIX_FMT_RGBX_5551,
  94. SDE_PIX_FMT_XBGR_1555,
  95. SDE_PIX_FMT_XRGB_1555,
  96. SDE_PIX_FMT_ARGB_4444,
  97. SDE_PIX_FMT_RGBA_4444,
  98. SDE_PIX_FMT_BGRA_4444,
  99. SDE_PIX_FMT_ABGR_4444,
  100. SDE_PIX_FMT_RGBX_4444,
  101. SDE_PIX_FMT_XRGB_4444,
  102. SDE_PIX_FMT_BGRX_4444,
  103. SDE_PIX_FMT_XBGR_4444,
  104. SDE_PIX_FMT_RGB_888,
  105. SDE_PIX_FMT_BGR_888,
  106. SDE_PIX_FMT_RGB_565,
  107. SDE_PIX_FMT_BGR_565,
  108. SDE_PIX_FMT_Y_CB_CR_H2V2,
  109. SDE_PIX_FMT_Y_CR_CB_H2V2,
  110. SDE_PIX_FMT_Y_CR_CB_GH2V2,
  111. SDE_PIX_FMT_Y_CBCR_H2V2,
  112. SDE_PIX_FMT_Y_CRCB_H2V2,
  113. SDE_PIX_FMT_Y_CBCR_H1V2,
  114. SDE_PIX_FMT_Y_CRCB_H1V2,
  115. SDE_PIX_FMT_Y_CBCR_H2V1,
  116. SDE_PIX_FMT_Y_CRCB_H2V1,
  117. SDE_PIX_FMT_YCBYCR_H2V1,
  118. SDE_PIX_FMT_Y_CBCR_H2V2_VENUS,
  119. SDE_PIX_FMT_Y_CRCB_H2V2_VENUS,
  120. SDE_PIX_FMT_RGBA_8888_UBWC,
  121. SDE_PIX_FMT_RGBX_8888_UBWC,
  122. SDE_PIX_FMT_RGB_565_UBWC,
  123. SDE_PIX_FMT_Y_CBCR_H2V2_UBWC,
  124. };
  125. static struct sde_mdp_hw_resource *sde_rotator_hw_alloc(
  126. struct sde_rot_mgr *mgr, u32 ctl_id, u32 wb_id, int irq_num)
  127. {
  128. struct sde_mdp_hw_resource *mdp_hw;
  129. struct sde_rot_data_type *mdata = sde_rot_get_mdata();
  130. int pipe_ndx, offset = ctl_id;
  131. int ret = 0;
  132. mdp_hw = devm_kzalloc(&mgr->pdev->dev,
  133. sizeof(struct sde_mdp_hw_resource), GFP_KERNEL);
  134. if (!mdp_hw)
  135. return ERR_PTR(-ENOMEM);
  136. mdp_hw->ctl = sde_mdp_ctl_alloc(mdata, offset);
  137. if (IS_ERR_OR_NULL(mdp_hw->ctl)) {
  138. SDEROT_ERR("unable to allocate ctl\n");
  139. ret = -ENODEV;
  140. goto error;
  141. }
  142. mdp_hw->ctl->irq_num = irq_num;
  143. mdp_hw->wb = sde_mdp_wb_assign(wb_id, mdp_hw->ctl->num);
  144. if (IS_ERR_OR_NULL(mdp_hw->wb)) {
  145. SDEROT_ERR("unable to allocate wb\n");
  146. ret = -ENODEV;
  147. goto error;
  148. }
  149. mdp_hw->ctl->wb = mdp_hw->wb;
  150. mdp_hw->mixer = sde_mdp_mixer_assign(mdp_hw->wb->num, true);
  151. if (IS_ERR_OR_NULL(mdp_hw->mixer)) {
  152. SDEROT_ERR("unable to allocate wb mixer\n");
  153. ret = -ENODEV;
  154. goto error;
  155. }
  156. mdp_hw->ctl->mixer_left = mdp_hw->mixer;
  157. mdp_hw->mixer->ctl = mdp_hw->ctl;
  158. mdp_hw->mixer->rotator_mode = true;
  159. switch (mdp_hw->mixer->num) {
  160. case SDE_MDP_WB_LAYERMIXER0:
  161. mdp_hw->ctl->opmode = SDE_MDP_CTL_OP_ROT0_MODE;
  162. break;
  163. case SDE_MDP_WB_LAYERMIXER1:
  164. mdp_hw->ctl->opmode = SDE_MDP_CTL_OP_ROT1_MODE;
  165. break;
  166. default:
  167. SDEROT_ERR("invalid layer mixer=%d\n", mdp_hw->mixer->num);
  168. ret = -EINVAL;
  169. goto error;
  170. }
  171. mdp_hw->ctl->ops.start_fnc = sde_mdp_writeback_start;
  172. mdp_hw->ctl->wb_type = SDE_MDP_WB_CTL_TYPE_BLOCK;
  173. if (mdp_hw->ctl->ops.start_fnc)
  174. ret = mdp_hw->ctl->ops.start_fnc(mdp_hw->ctl);
  175. if (ret)
  176. goto error;
  177. /* override from dt */
  178. pipe_ndx = wb_id;
  179. mdp_hw->pipe = sde_mdp_pipe_assign(mdata, mdp_hw->mixer, pipe_ndx);
  180. if (IS_ERR_OR_NULL(mdp_hw->pipe)) {
  181. SDEROT_ERR("dma pipe allocation failed\n");
  182. ret = -ENODEV;
  183. goto error;
  184. }
  185. mdp_hw->pipe->mixer_left = mdp_hw->mixer;
  186. mdp_hw->hw.wb_id = mdp_hw->wb->num;
  187. mdp_hw->hw.pending_count = 0;
  188. atomic_set(&mdp_hw->hw.num_active, 0);
  189. mdp_hw->hw.max_active = 1;
  190. init_waitqueue_head(&mdp_hw->hw.wait_queue);
  191. return mdp_hw;
  192. error:
  193. if (!IS_ERR_OR_NULL(mdp_hw->pipe))
  194. sde_mdp_pipe_destroy(mdp_hw->pipe);
  195. if (!IS_ERR_OR_NULL(mdp_hw->ctl)) {
  196. if (mdp_hw->ctl->ops.stop_fnc)
  197. mdp_hw->ctl->ops.stop_fnc(mdp_hw->ctl, 0);
  198. sde_mdp_ctl_free(mdp_hw->ctl);
  199. }
  200. devm_kfree(&mgr->pdev->dev, mdp_hw);
  201. return ERR_PTR(ret);
  202. }
  203. static void sde_rotator_hw_free(struct sde_rot_mgr *mgr,
  204. struct sde_mdp_hw_resource *mdp_hw)
  205. {
  206. struct sde_mdp_mixer *mixer;
  207. struct sde_mdp_ctl *ctl;
  208. if (!mgr || !mdp_hw)
  209. return;
  210. mixer = mdp_hw->pipe->mixer_left;
  211. sde_mdp_pipe_destroy(mdp_hw->pipe);
  212. ctl = sde_mdp_ctl_mixer_switch(mixer->ctl,
  213. SDE_MDP_WB_CTL_TYPE_BLOCK);
  214. if (ctl) {
  215. if (ctl->ops.stop_fnc)
  216. ctl->ops.stop_fnc(ctl, 0);
  217. sde_mdp_ctl_free(ctl);
  218. }
  219. devm_kfree(&mgr->pdev->dev, mdp_hw);
  220. }
  221. static struct sde_rot_hw_resource *sde_rotator_hw_alloc_ext(
  222. struct sde_rot_mgr *mgr, u32 pipe_id, u32 wb_id)
  223. {
  224. struct sde_mdp_hw_resource *mdp_hw;
  225. struct sde_rotator_r1_data *hw_data;
  226. if (!mgr || !mgr->hw_data)
  227. return NULL;
  228. hw_data = mgr->hw_data;
  229. mdp_hw = hw_data->mdp_hw;
  230. return &mdp_hw->hw;
  231. }
  232. static void sde_rotator_hw_free_ext(struct sde_rot_mgr *mgr,
  233. struct sde_rot_hw_resource *hw)
  234. {
  235. /* currently nothing specific for this device */
  236. }
  237. static void sde_rotator_translate_rect(struct sde_rect *dst,
  238. struct sde_rect *src)
  239. {
  240. dst->x = src->x;
  241. dst->y = src->y;
  242. dst->w = src->w;
  243. dst->h = src->h;
  244. }
  245. static u32 sde_rotator_translate_flags(u32 input)
  246. {
  247. u32 output = 0;
  248. if (input & SDE_ROTATION_NOP)
  249. output |= SDE_ROT_NOP;
  250. if (input & SDE_ROTATION_FLIP_LR)
  251. output |= SDE_FLIP_LR;
  252. if (input & SDE_ROTATION_FLIP_UD)
  253. output |= SDE_FLIP_UD;
  254. if (input & SDE_ROTATION_90)
  255. output |= SDE_ROT_90;
  256. if (input & SDE_ROTATION_DEINTERLACE)
  257. output |= SDE_DEINTERLACE;
  258. if (input & SDE_ROTATION_SECURE)
  259. output |= SDE_SECURE_OVERLAY_SESSION;
  260. return output;
  261. }
  262. static int sde_rotator_config_hw(struct sde_rot_hw_resource *hw,
  263. struct sde_rot_entry *entry)
  264. {
  265. struct sde_mdp_hw_resource *mdp_hw;
  266. struct sde_mdp_pipe *pipe;
  267. struct sde_rotation_item *item;
  268. int ret;
  269. if (!hw || !entry) {
  270. SDEROT_ERR("null hw resource/entry");
  271. return -EINVAL;
  272. }
  273. mdp_hw = container_of(hw, struct sde_mdp_hw_resource, hw);
  274. pipe = mdp_hw->pipe;
  275. item = &entry->item;
  276. pipe->flags = sde_rotator_translate_flags(item->flags);
  277. pipe->src_fmt = sde_get_format_params(item->input.format);
  278. pipe->img_width = item->input.width;
  279. pipe->img_height = item->input.height;
  280. sde_rotator_translate_rect(&pipe->src, &item->src_rect);
  281. sde_rotator_translate_rect(&pipe->dst, &item->src_rect);
  282. pipe->params_changed++;
  283. ret = sde_mdp_pipe_queue_data(pipe, &entry->src_buf);
  284. SDEROT_DBG("Config pipe. src{%u,%u,%u,%u}f=%u\n"
  285. "dst{%u,%u,%u,%u}f=%u session_id=%u\n",
  286. item->src_rect.x, item->src_rect.y,
  287. item->src_rect.w, item->src_rect.h, item->input.format,
  288. item->dst_rect.x, item->dst_rect.y,
  289. item->dst_rect.w, item->dst_rect.h, item->output.format,
  290. item->session_id);
  291. return ret;
  292. }
  293. static int sde_rotator_cancel_hw(struct sde_rot_hw_resource *hw,
  294. struct sde_rot_entry *entry)
  295. {
  296. return 0;
  297. }
  298. static int sde_rotator_abort_hw(struct sde_rot_hw_resource *hw,
  299. struct sde_rot_entry *entry)
  300. {
  301. return 0;
  302. }
  303. static int sde_rotator_kickoff_entry(struct sde_rot_hw_resource *hw,
  304. struct sde_rot_entry *entry)
  305. {
  306. struct sde_mdp_hw_resource *mdp_hw;
  307. int ret;
  308. struct sde_mdp_writeback_arg wb_args;
  309. if (!hw || !entry) {
  310. SDEROT_ERR("null hw resource/entry");
  311. return -EINVAL;
  312. }
  313. wb_args.data = &entry->dst_buf;
  314. wb_args.priv_data = entry;
  315. mdp_hw = container_of(hw, struct sde_mdp_hw_resource, hw);
  316. ret = sde_mdp_writeback_display_commit(mdp_hw->ctl, &wb_args);
  317. return ret;
  318. }
  319. static int sde_rotator_wait_for_entry(struct sde_rot_hw_resource *hw,
  320. struct sde_rot_entry *entry)
  321. {
  322. struct sde_mdp_hw_resource *mdp_hw;
  323. int ret;
  324. struct sde_mdp_ctl *ctl;
  325. if (!hw || !entry) {
  326. SDEROT_ERR("null hw resource/entry");
  327. return -EINVAL;
  328. }
  329. mdp_hw = container_of(hw, struct sde_mdp_hw_resource, hw);
  330. ctl = mdp_hw->ctl;
  331. ret = sde_mdp_display_wait4comp(ctl);
  332. return ret;
  333. }
  334. static int sde_rotator_hw_validate_entry(struct sde_rot_mgr *mgr,
  335. struct sde_rot_entry *entry)
  336. {
  337. int ret = 0;
  338. u16 src_w, src_h, dst_w, dst_h, bit;
  339. struct sde_rotation_item *item = &entry->item;
  340. struct sde_mdp_format_params *fmt;
  341. src_w = item->src_rect.w;
  342. src_h = item->src_rect.h;
  343. if (item->flags & SDE_ROTATION_90) {
  344. dst_w = item->dst_rect.h;
  345. dst_h = item->dst_rect.w;
  346. } else {
  347. dst_w = item->dst_rect.w;
  348. dst_h = item->dst_rect.h;
  349. }
  350. entry->dnsc_factor_w = 0;
  351. entry->dnsc_factor_h = 0;
  352. if ((src_w != dst_w) || (src_h != dst_h)) {
  353. if ((src_w % dst_w) || (src_h % dst_h)) {
  354. SDEROT_DBG("non integral scale not support\n");
  355. ret = -EINVAL;
  356. goto dnsc_err;
  357. }
  358. entry->dnsc_factor_w = src_w / dst_w;
  359. bit = fls(entry->dnsc_factor_w);
  360. if ((entry->dnsc_factor_w & ~BIT(bit - 1)) || (bit > 5)) {
  361. SDEROT_DBG("non power-of-2 scale not support\n");
  362. ret = -EINVAL;
  363. goto dnsc_err;
  364. }
  365. entry->dnsc_factor_h = src_h / dst_h;
  366. bit = fls(entry->dnsc_factor_h);
  367. if ((entry->dnsc_factor_h & ~BIT(bit - 1)) || (bit > 5)) {
  368. SDEROT_DBG("non power-of-2 dscale not support\n");
  369. ret = -EINVAL;
  370. goto dnsc_err;
  371. }
  372. }
  373. fmt = sde_get_format_params(item->output.format);
  374. if (sde_mdp_is_ubwc_format(fmt) &&
  375. (entry->dnsc_factor_h || entry->dnsc_factor_w)) {
  376. SDEROT_DBG("downscale with ubwc not support\n");
  377. ret = -EINVAL;
  378. }
  379. dnsc_err:
  380. /* Downscaler does not support asymmetrical dnsc */
  381. if (entry->dnsc_factor_w != entry->dnsc_factor_h) {
  382. SDEROT_DBG("asymmetric downscale not support\n");
  383. ret = -EINVAL;
  384. }
  385. if (ret) {
  386. entry->dnsc_factor_w = 0;
  387. entry->dnsc_factor_h = 0;
  388. }
  389. return ret;
  390. }
  391. static ssize_t sde_rotator_hw_show_caps(struct sde_rot_mgr *mgr,
  392. struct device_attribute *attr, char *buf, ssize_t len)
  393. {
  394. struct sde_rotator_r1_data *hw_data;
  395. int cnt = 0;
  396. if (!mgr || !buf)
  397. return 0;
  398. hw_data = mgr->hw_data;
  399. #define SPRINT(fmt, ...) \
  400. (cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__))
  401. SPRINT("wb_id=%d\n", hw_data->wb_id);
  402. SPRINT("ctl_id=%d\n", hw_data->ctl_id);
  403. return cnt;
  404. }
  405. static ssize_t sde_rotator_hw_show_state(struct sde_rot_mgr *mgr,
  406. struct device_attribute *attr, char *buf, ssize_t len)
  407. {
  408. struct sde_rotator_r1_data *hw_data;
  409. int cnt = 0;
  410. if (!mgr || !buf)
  411. return 0;
  412. hw_data = mgr->hw_data;
  413. #define SPRINT(fmt, ...) \
  414. (cnt += scnprintf(buf + cnt, len - cnt, fmt, ##__VA_ARGS__))
  415. if (hw_data && hw_data->mdp_hw) {
  416. struct sde_rot_hw_resource *hw = &hw_data->mdp_hw->hw;
  417. SPRINT("irq_num=%d\n", hw_data->irq_num);
  418. SPRINT("max_active=%d\n", hw->max_active);
  419. SPRINT("num_active=%d\n", atomic_read(&hw->num_active));
  420. SPRINT("pending_cnt=%u\n", hw->pending_count);
  421. }
  422. return cnt;
  423. }
  424. /*
  425. * sde_hw_rotator_get_pixfmt - get the indexed pixel format
  426. * @mgr: Pointer to rotator manager
  427. * @index: index of pixel format
  428. * @input: true for input port; false for output port
  429. * @mode: operating mode
  430. */
  431. static u32 sde_hw_rotator_get_pixfmt(struct sde_rot_mgr *mgr,
  432. int index, bool input, u32 mode)
  433. {
  434. if (input) {
  435. if (index < ARRAY_SIZE(sde_hw_rotator_input_pixfmts))
  436. return sde_hw_rotator_input_pixfmts[index];
  437. else
  438. return 0;
  439. } else {
  440. if (index < ARRAY_SIZE(sde_hw_rotator_output_pixfmts))
  441. return sde_hw_rotator_output_pixfmts[index];
  442. else
  443. return 0;
  444. }
  445. }
  446. /*
  447. * sde_hw_rotator_is_valid_pixfmt - verify if the given pixel format is valid
  448. * @mgr: Pointer to rotator manager
  449. * @pixfmt: pixel format to be verified
  450. * @input: true for input port; false for output port
  451. * @mode: operating mode
  452. */
  453. static int sde_hw_rotator_is_valid_pixfmt(struct sde_rot_mgr *mgr, u32 pixfmt,
  454. bool input, u32 mode)
  455. {
  456. int i;
  457. if (input) {
  458. for (i = 0; i < ARRAY_SIZE(sde_hw_rotator_input_pixfmts); i++)
  459. if (sde_hw_rotator_input_pixfmts[i] == pixfmt)
  460. return true;
  461. } else {
  462. for (i = 0; i < ARRAY_SIZE(sde_hw_rotator_output_pixfmts); i++)
  463. if (sde_hw_rotator_output_pixfmts[i] == pixfmt)
  464. return true;
  465. }
  466. return false;
  467. }
  468. static int sde_rotator_hw_parse_dt(struct sde_rotator_r1_data *hw_data,
  469. struct platform_device *dev)
  470. {
  471. int ret = 0;
  472. u32 data;
  473. if (!hw_data || !dev)
  474. return -EINVAL;
  475. ret = of_property_read_u32(dev->dev.of_node,
  476. "qcom,mdss-wb-id", &data);
  477. if (ret)
  478. hw_data->wb_id = -1;
  479. else
  480. hw_data->wb_id = (int) data;
  481. ret = of_property_read_u32(dev->dev.of_node,
  482. "qcom,mdss-ctl-id", &data);
  483. if (ret)
  484. hw_data->ctl_id = -1;
  485. else
  486. hw_data->ctl_id = (int) data;
  487. return ret;
  488. }
  489. static int sde_rotator_hw_rev_init(struct sde_rot_data_type *mdata)
  490. {
  491. if (!mdata) {
  492. SDEROT_ERR("null rotator data\n");
  493. return -EINVAL;
  494. }
  495. clear_bit(SDE_QOS_PER_PIPE_IB, mdata->sde_qos_map);
  496. set_bit(SDE_QOS_OVERHEAD_FACTOR, mdata->sde_qos_map);
  497. clear_bit(SDE_QOS_CDP, mdata->sde_qos_map);
  498. set_bit(SDE_QOS_OTLIM, mdata->sde_qos_map);
  499. set_bit(SDE_QOS_PER_PIPE_LUT, mdata->sde_qos_map);
  500. clear_bit(SDE_QOS_SIMPLIFIED_PREFILL, mdata->sde_qos_map);
  501. set_bit(SDE_CAPS_R1_WB, mdata->sde_caps_map);
  502. return 0;
  503. }
  504. enum {
  505. SDE_ROTATOR_INTR_WB_0,
  506. SDE_ROTATOR_INTR_WB_1,
  507. SDE_ROTATOR_INTR_MAX,
  508. };
  509. struct intr_callback {
  510. void (*func)(void *data);
  511. void *arg;
  512. };
  513. struct intr_callback sde_intr_cb[SDE_ROTATOR_INTR_MAX];
  514. int sde_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
  515. void (*fnc_ptr)(void *), void *arg)
  516. {
  517. if (intf_num >= SDE_ROTATOR_INTR_MAX) {
  518. SDEROT_WARN("invalid intr type=%u intf_num=%u\n",
  519. intr_type, intf_num);
  520. return -EINVAL;
  521. }
  522. sde_intr_cb[intf_num].func = fnc_ptr;
  523. sde_intr_cb[intf_num].arg = arg;
  524. return 0;
  525. }
  526. static irqreturn_t sde_irq_handler(int irq, void *ptr)
  527. {
  528. struct sde_rot_data_type *mdata = ptr;
  529. irqreturn_t ret = IRQ_NONE;
  530. u32 isr;
  531. isr = readl_relaxed(mdata->mdp_base + SDE_MDP_REG_INTR_STATUS);
  532. SDEROT_DBG("intr_status = %8.8x\n", isr);
  533. if (isr & SDE_MDP_INTR_WB_0_DONE) {
  534. struct intr_callback *cb = &sde_intr_cb[SDE_ROTATOR_INTR_WB_0];
  535. if (cb->func) {
  536. writel_relaxed(SDE_MDP_INTR_WB_0_DONE,
  537. mdata->mdp_base + SDE_MDP_REG_INTR_CLEAR);
  538. cb->func(cb->arg);
  539. ret = IRQ_HANDLED;
  540. }
  541. }
  542. if (isr & SDE_MDP_INTR_WB_1_DONE) {
  543. struct intr_callback *cb = &sde_intr_cb[SDE_ROTATOR_INTR_WB_1];
  544. if (cb->func) {
  545. writel_relaxed(SDE_MDP_INTR_WB_1_DONE,
  546. mdata->mdp_base + SDE_MDP_REG_INTR_CLEAR);
  547. cb->func(cb->arg);
  548. ret = IRQ_HANDLED;
  549. }
  550. }
  551. return ret;
  552. }
  553. static void sde_rotator_hw_destroy(struct sde_rot_mgr *mgr)
  554. {
  555. struct sde_rot_data_type *mdata = sde_rot_get_mdata();
  556. struct sde_rotator_r1_data *hw_data;
  557. if (!mgr || !mgr->pdev || !mgr->hw_data)
  558. return;
  559. hw_data = mgr->hw_data;
  560. if (hw_data->irq_num >= 0)
  561. devm_free_irq(&mgr->pdev->dev, hw_data->irq_num, mdata);
  562. sde_rotator_hw_free(mgr, hw_data->mdp_hw);
  563. devm_kfree(&mgr->pdev->dev, mgr->hw_data);
  564. mgr->hw_data = NULL;
  565. }
  566. int sde_rotator_r1_init(struct sde_rot_mgr *mgr)
  567. {
  568. struct sde_rot_data_type *mdata = sde_rot_get_mdata();
  569. struct sde_rotator_r1_data *hw_data;
  570. int ret;
  571. if (!mgr || !mgr->pdev) {
  572. SDEROT_ERR("null rotator manager/platform device");
  573. return -EINVAL;
  574. }
  575. hw_data = devm_kzalloc(&mgr->pdev->dev,
  576. sizeof(struct sde_rotator_r1_data), GFP_KERNEL);
  577. if (hw_data == NULL)
  578. return -ENOMEM;
  579. mgr->hw_data = hw_data;
  580. mgr->ops_config_hw = sde_rotator_config_hw;
  581. mgr->ops_cancel_hw = sde_rotator_cancel_hw;
  582. mgr->ops_abort_hw = sde_rotator_abort_hw;
  583. mgr->ops_kickoff_entry = sde_rotator_kickoff_entry;
  584. mgr->ops_wait_for_entry = sde_rotator_wait_for_entry;
  585. mgr->ops_hw_alloc = sde_rotator_hw_alloc_ext;
  586. mgr->ops_hw_free = sde_rotator_hw_free_ext;
  587. mgr->ops_hw_destroy = sde_rotator_hw_destroy;
  588. mgr->ops_hw_validate_entry = sde_rotator_hw_validate_entry;
  589. mgr->ops_hw_show_caps = sde_rotator_hw_show_caps;
  590. mgr->ops_hw_show_state = sde_rotator_hw_show_state;
  591. mgr->ops_hw_create_debugfs = sde_rotator_r1_create_debugfs;
  592. mgr->ops_hw_get_pixfmt = sde_hw_rotator_get_pixfmt;
  593. mgr->ops_hw_is_valid_pixfmt = sde_hw_rotator_is_valid_pixfmt;
  594. ret = sde_rotator_hw_parse_dt(mgr->hw_data, mgr->pdev);
  595. if (ret)
  596. goto error_parse_dt;
  597. hw_data->irq_num = platform_get_irq(mgr->pdev, 0);
  598. if (hw_data->irq_num < 0) {
  599. SDEROT_ERR("fail to get rotator irq\n");
  600. } else {
  601. ret = devm_request_threaded_irq(&mgr->pdev->dev,
  602. hw_data->irq_num,
  603. sde_irq_handler, NULL,
  604. 0, "sde_rotator_r1", mdata);
  605. if (ret) {
  606. SDEROT_ERR("fail to request irq r:%d\n", ret);
  607. hw_data->irq_num = -1;
  608. } else {
  609. disable_irq(hw_data->irq_num);
  610. }
  611. }
  612. hw_data->mdp_hw = sde_rotator_hw_alloc(mgr, hw_data->ctl_id,
  613. hw_data->wb_id, hw_data->irq_num);
  614. if (IS_ERR_OR_NULL(hw_data->mdp_hw))
  615. goto error_hw_alloc;
  616. ret = sde_rotator_hw_rev_init(sde_rot_get_mdata());
  617. if (ret)
  618. goto error_hw_rev_init;
  619. hw_data->mgr = mgr;
  620. return 0;
  621. error_hw_rev_init:
  622. if (hw_data->irq_num >= 0)
  623. devm_free_irq(&mgr->pdev->dev, hw_data->irq_num, mdata);
  624. sde_rotator_hw_free(mgr, hw_data->mdp_hw);
  625. error_hw_alloc:
  626. devm_kfree(&mgr->pdev->dev, mgr->hw_data);
  627. error_parse_dt:
  628. return ret;
  629. }