sun4i_backend.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. /*
  2. * Copyright (C) 2015 Free Electrons
  3. * Copyright (C) 2015 NextThing Co
  4. *
  5. * Maxime Ripard <maxime.ripard@free-electrons.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. */
  12. #include <drm/drmP.h>
  13. #include <drm/drm_atomic.h>
  14. #include <drm/drm_atomic_helper.h>
  15. #include <drm/drm_crtc.h>
  16. #include <drm/drm_crtc_helper.h>
  17. #include <drm/drm_fb_cma_helper.h>
  18. #include <drm/drm_gem_cma_helper.h>
  19. #include <drm/drm_plane_helper.h>
  20. #include <linux/component.h>
  21. #include <linux/list.h>
  22. #include <linux/of_device.h>
  23. #include <linux/of_graph.h>
  24. #include <linux/reset.h>
  25. #include "sun4i_backend.h"
  26. #include "sun4i_drv.h"
  27. #include "sun4i_frontend.h"
  28. #include "sun4i_layer.h"
  29. #include "sunxi_engine.h"
  30. struct sun4i_backend_quirks {
  31. /* backend <-> TCON muxing selection done in backend */
  32. bool needs_output_muxing;
  33. };
  34. static const u32 sunxi_rgb2yuv_coef[12] = {
  35. 0x00000107, 0x00000204, 0x00000064, 0x00000108,
  36. 0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808,
  37. 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808
  38. };
  39. /*
  40. * These coefficients are taken from the A33 BSP from Allwinner.
  41. *
  42. * The formula is for each component, each coefficient being multiplied by
  43. * 1024 and each constant being multiplied by 16:
  44. * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135
  45. * R = 1.164 * Y + 1.596 * V - 222
  46. * B = 1.164 * Y + 2.018 * U + 276
  47. *
  48. * This seems to be a conversion from Y[16:235] UV[16:240] to RGB[0:255],
  49. * following the BT601 spec.
  50. */
  51. static const u32 sunxi_bt601_yuv2rgb_coef[12] = {
  52. 0x000004a7, 0x00001e6f, 0x00001cbf, 0x00000877,
  53. 0x000004a7, 0x00000000, 0x00000662, 0x00003211,
  54. 0x000004a7, 0x00000812, 0x00000000, 0x00002eb1,
  55. };
  56. static inline bool sun4i_backend_format_is_planar_yuv(uint32_t format)
  57. {
  58. switch (format) {
  59. case DRM_FORMAT_YUV411:
  60. case DRM_FORMAT_YUV422:
  61. case DRM_FORMAT_YUV444:
  62. return true;
  63. default:
  64. return false;
  65. }
  66. }
  67. static inline bool sun4i_backend_format_is_packed_yuv422(uint32_t format)
  68. {
  69. switch (format) {
  70. case DRM_FORMAT_YUYV:
  71. case DRM_FORMAT_YVYU:
  72. case DRM_FORMAT_UYVY:
  73. case DRM_FORMAT_VYUY:
  74. return true;
  75. default:
  76. return false;
  77. }
  78. }
  79. static inline bool sun4i_backend_format_is_yuv(uint32_t format)
  80. {
  81. return sun4i_backend_format_is_planar_yuv(format) ||
  82. sun4i_backend_format_is_packed_yuv422(format);
  83. }
  84. static void sun4i_backend_apply_color_correction(struct sunxi_engine *engine)
  85. {
  86. int i;
  87. DRM_DEBUG_DRIVER("Applying RGB to YUV color correction\n");
  88. /* Set color correction */
  89. regmap_write(engine->regs, SUN4I_BACKEND_OCCTL_REG,
  90. SUN4I_BACKEND_OCCTL_ENABLE);
  91. for (i = 0; i < 12; i++)
  92. regmap_write(engine->regs, SUN4I_BACKEND_OCRCOEF_REG(i),
  93. sunxi_rgb2yuv_coef[i]);
  94. }
  95. static void sun4i_backend_disable_color_correction(struct sunxi_engine *engine)
  96. {
  97. DRM_DEBUG_DRIVER("Disabling color correction\n");
  98. /* Disable color correction */
  99. regmap_update_bits(engine->regs, SUN4I_BACKEND_OCCTL_REG,
  100. SUN4I_BACKEND_OCCTL_ENABLE, 0);
  101. }
  102. static void sun4i_backend_commit(struct sunxi_engine *engine)
  103. {
  104. DRM_DEBUG_DRIVER("Committing changes\n");
  105. regmap_write(engine->regs, SUN4I_BACKEND_REGBUFFCTL_REG,
  106. SUN4I_BACKEND_REGBUFFCTL_AUTOLOAD_DIS |
  107. SUN4I_BACKEND_REGBUFFCTL_LOADCTL);
  108. }
  109. void sun4i_backend_layer_enable(struct sun4i_backend *backend,
  110. int layer, bool enable)
  111. {
  112. u32 val;
  113. DRM_DEBUG_DRIVER("%sabling layer %d\n", enable ? "En" : "Dis",
  114. layer);
  115. if (enable)
  116. val = SUN4I_BACKEND_MODCTL_LAY_EN(layer);
  117. else
  118. val = 0;
  119. regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG,
  120. SUN4I_BACKEND_MODCTL_LAY_EN(layer), val);
  121. }
  122. static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode)
  123. {
  124. switch (format) {
  125. case DRM_FORMAT_ARGB8888:
  126. *mode = SUN4I_BACKEND_LAY_FBFMT_ARGB8888;
  127. break;
  128. case DRM_FORMAT_ARGB4444:
  129. *mode = SUN4I_BACKEND_LAY_FBFMT_ARGB4444;
  130. break;
  131. case DRM_FORMAT_ARGB1555:
  132. *mode = SUN4I_BACKEND_LAY_FBFMT_ARGB1555;
  133. break;
  134. case DRM_FORMAT_RGBA5551:
  135. *mode = SUN4I_BACKEND_LAY_FBFMT_RGBA5551;
  136. break;
  137. case DRM_FORMAT_RGBA4444:
  138. *mode = SUN4I_BACKEND_LAY_FBFMT_RGBA4444;
  139. break;
  140. case DRM_FORMAT_XRGB8888:
  141. *mode = SUN4I_BACKEND_LAY_FBFMT_XRGB8888;
  142. break;
  143. case DRM_FORMAT_RGB888:
  144. *mode = SUN4I_BACKEND_LAY_FBFMT_RGB888;
  145. break;
  146. case DRM_FORMAT_RGB565:
  147. *mode = SUN4I_BACKEND_LAY_FBFMT_RGB565;
  148. break;
  149. default:
  150. return -EINVAL;
  151. }
  152. return 0;
  153. }
  154. int sun4i_backend_update_layer_coord(struct sun4i_backend *backend,
  155. int layer, struct drm_plane *plane)
  156. {
  157. struct drm_plane_state *state = plane->state;
  158. DRM_DEBUG_DRIVER("Updating layer %d\n", layer);
  159. if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
  160. DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
  161. state->crtc_w, state->crtc_h);
  162. regmap_write(backend->engine.regs, SUN4I_BACKEND_DISSIZE_REG,
  163. SUN4I_BACKEND_DISSIZE(state->crtc_w,
  164. state->crtc_h));
  165. }
  166. /* Set height and width */
  167. DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n",
  168. state->crtc_w, state->crtc_h);
  169. regmap_write(backend->engine.regs, SUN4I_BACKEND_LAYSIZE_REG(layer),
  170. SUN4I_BACKEND_LAYSIZE(state->crtc_w,
  171. state->crtc_h));
  172. /* Set base coordinates */
  173. DRM_DEBUG_DRIVER("Layer coordinates X: %d Y: %d\n",
  174. state->crtc_x, state->crtc_y);
  175. regmap_write(backend->engine.regs, SUN4I_BACKEND_LAYCOOR_REG(layer),
  176. SUN4I_BACKEND_LAYCOOR(state->crtc_x,
  177. state->crtc_y));
  178. return 0;
  179. }
  180. static int sun4i_backend_update_yuv_format(struct sun4i_backend *backend,
  181. int layer, struct drm_plane *plane)
  182. {
  183. struct drm_plane_state *state = plane->state;
  184. struct drm_framebuffer *fb = state->fb;
  185. uint32_t format = fb->format->format;
  186. u32 val = SUN4I_BACKEND_IYUVCTL_EN;
  187. int i;
  188. for (i = 0; i < ARRAY_SIZE(sunxi_bt601_yuv2rgb_coef); i++)
  189. regmap_write(backend->engine.regs,
  190. SUN4I_BACKEND_YGCOEF_REG(i),
  191. sunxi_bt601_yuv2rgb_coef[i]);
  192. /*
  193. * We should do that only for a single plane, but the
  194. * framebuffer's atomic_check has our back on this.
  195. */
  196. regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
  197. SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN,
  198. SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN);
  199. /* TODO: Add support for the multi-planar YUV formats */
  200. if (sun4i_backend_format_is_packed_yuv422(format))
  201. val |= SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV422;
  202. else
  203. DRM_DEBUG_DRIVER("Unsupported YUV format (0x%x)\n", format);
  204. /*
  205. * Allwinner seems to list the pixel sequence from right to left, while
  206. * DRM lists it from left to right.
  207. */
  208. switch (format) {
  209. case DRM_FORMAT_YUYV:
  210. val |= SUN4I_BACKEND_IYUVCTL_FBPS_VYUY;
  211. break;
  212. case DRM_FORMAT_YVYU:
  213. val |= SUN4I_BACKEND_IYUVCTL_FBPS_UYVY;
  214. break;
  215. case DRM_FORMAT_UYVY:
  216. val |= SUN4I_BACKEND_IYUVCTL_FBPS_YVYU;
  217. break;
  218. case DRM_FORMAT_VYUY:
  219. val |= SUN4I_BACKEND_IYUVCTL_FBPS_YUYV;
  220. break;
  221. default:
  222. DRM_DEBUG_DRIVER("Unsupported YUV pixel sequence (0x%x)\n",
  223. format);
  224. }
  225. regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVCTL_REG, val);
  226. return 0;
  227. }
  228. int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
  229. int layer, struct drm_plane *plane)
  230. {
  231. struct drm_plane_state *state = plane->state;
  232. struct drm_framebuffer *fb = state->fb;
  233. bool interlaced = false;
  234. u32 val;
  235. int ret;
  236. /* Clear the YUV mode */
  237. regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
  238. SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN, 0);
  239. if (plane->state->crtc)
  240. interlaced = plane->state->crtc->state->adjusted_mode.flags
  241. & DRM_MODE_FLAG_INTERLACE;
  242. regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG,
  243. SUN4I_BACKEND_MODCTL_ITLMOD_EN,
  244. interlaced ? SUN4I_BACKEND_MODCTL_ITLMOD_EN : 0);
  245. DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n",
  246. interlaced ? "on" : "off");
  247. if (sun4i_backend_format_is_yuv(fb->format->format))
  248. return sun4i_backend_update_yuv_format(backend, layer, plane);
  249. ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val);
  250. if (ret) {
  251. DRM_DEBUG_DRIVER("Invalid format\n");
  252. return ret;
  253. }
  254. regmap_update_bits(backend->engine.regs,
  255. SUN4I_BACKEND_ATTCTL_REG1(layer),
  256. SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);
  257. return 0;
  258. }
  259. int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend,
  260. int layer, uint32_t fmt)
  261. {
  262. u32 val;
  263. int ret;
  264. ret = sun4i_backend_drm_format_to_layer(fmt, &val);
  265. if (ret) {
  266. DRM_DEBUG_DRIVER("Invalid format\n");
  267. return ret;
  268. }
  269. regmap_update_bits(backend->engine.regs,
  270. SUN4I_BACKEND_ATTCTL_REG0(layer),
  271. SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN,
  272. SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN);
  273. regmap_update_bits(backend->engine.regs,
  274. SUN4I_BACKEND_ATTCTL_REG1(layer),
  275. SUN4I_BACKEND_ATTCTL_REG1_LAY_FBFMT, val);
  276. return 0;
  277. }
  278. static int sun4i_backend_update_yuv_buffer(struct sun4i_backend *backend,
  279. struct drm_framebuffer *fb,
  280. dma_addr_t paddr)
  281. {
  282. /* TODO: Add support for the multi-planar YUV formats */
  283. DRM_DEBUG_DRIVER("Setting packed YUV buffer address to %pad\n", &paddr);
  284. regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVADD_REG(0), paddr);
  285. DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8);
  286. regmap_write(backend->engine.regs, SUN4I_BACKEND_IYUVLINEWIDTH_REG(0),
  287. fb->pitches[0] * 8);
  288. return 0;
  289. }
  290. int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
  291. int layer, struct drm_plane *plane)
  292. {
  293. struct drm_plane_state *state = plane->state;
  294. struct drm_framebuffer *fb = state->fb;
  295. u32 lo_paddr, hi_paddr;
  296. dma_addr_t paddr;
  297. /* Set the line width */
  298. DRM_DEBUG_DRIVER("Layer line width: %d bits\n", fb->pitches[0] * 8);
  299. regmap_write(backend->engine.regs,
  300. SUN4I_BACKEND_LAYLINEWIDTH_REG(layer),
  301. fb->pitches[0] * 8);
  302. /* Get the start of the displayed memory */
  303. paddr = drm_fb_cma_get_gem_addr(fb, state, 0);
  304. DRM_DEBUG_DRIVER("Setting buffer address to %pad\n", &paddr);
  305. /*
  306. * backend DMA accesses DRAM directly, bypassing the system
  307. * bus. As such, the address range is different and the buffer
  308. * address needs to be corrected.
  309. */
  310. paddr -= PHYS_OFFSET;
  311. if (sun4i_backend_format_is_yuv(fb->format->format))
  312. return sun4i_backend_update_yuv_buffer(backend, fb, paddr);
  313. /* Write the 32 lower bits of the address (in bits) */
  314. lo_paddr = paddr << 3;
  315. DRM_DEBUG_DRIVER("Setting address lower bits to 0x%x\n", lo_paddr);
  316. regmap_write(backend->engine.regs,
  317. SUN4I_BACKEND_LAYFB_L32ADD_REG(layer),
  318. lo_paddr);
  319. /* And the upper bits */
  320. hi_paddr = paddr >> 29;
  321. DRM_DEBUG_DRIVER("Setting address high bits to 0x%x\n", hi_paddr);
  322. regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_LAYFB_H4ADD_REG,
  323. SUN4I_BACKEND_LAYFB_H4ADD_MSK(layer),
  324. SUN4I_BACKEND_LAYFB_H4ADD(layer, hi_paddr));
  325. return 0;
  326. }
  327. int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer,
  328. struct drm_plane *plane)
  329. {
  330. struct drm_plane_state *state = plane->state;
  331. struct sun4i_layer_state *p_state = state_to_sun4i_layer_state(state);
  332. unsigned int priority = state->normalized_zpos;
  333. unsigned int pipe = p_state->pipe;
  334. DRM_DEBUG_DRIVER("Setting layer %d's priority to %d and pipe %d\n",
  335. layer, priority, pipe);
  336. regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
  337. SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK |
  338. SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK,
  339. SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(p_state->pipe) |
  340. SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority));
  341. return 0;
  342. }
  343. static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state)
  344. {
  345. u16 src_h = state->src_h >> 16;
  346. u16 src_w = state->src_w >> 16;
  347. DRM_DEBUG_DRIVER("Input size %dx%d, output size %dx%d\n",
  348. src_w, src_h, state->crtc_w, state->crtc_h);
  349. if ((state->crtc_h != src_h) || (state->crtc_w != src_w))
  350. return true;
  351. return false;
  352. }
  353. static bool sun4i_backend_plane_uses_frontend(struct drm_plane_state *state)
  354. {
  355. struct sun4i_layer *layer = plane_to_sun4i_layer(state->plane);
  356. struct sun4i_backend *backend = layer->backend;
  357. if (IS_ERR(backend->frontend))
  358. return false;
  359. return sun4i_backend_plane_uses_scaler(state);
  360. }
  361. static void sun4i_backend_atomic_begin(struct sunxi_engine *engine,
  362. struct drm_crtc_state *old_state)
  363. {
  364. u32 val;
  365. WARN_ON(regmap_read_poll_timeout(engine->regs,
  366. SUN4I_BACKEND_REGBUFFCTL_REG,
  367. val, !(val & SUN4I_BACKEND_REGBUFFCTL_LOADCTL),
  368. 100, 50000));
  369. }
  370. static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
  371. struct drm_crtc_state *crtc_state)
  372. {
  373. struct drm_plane_state *plane_states[SUN4I_BACKEND_NUM_LAYERS] = { 0 };
  374. struct drm_atomic_state *state = crtc_state->state;
  375. struct drm_device *drm = state->dev;
  376. struct drm_plane *plane;
  377. unsigned int num_planes = 0;
  378. unsigned int num_alpha_planes = 0;
  379. unsigned int num_frontend_planes = 0;
  380. unsigned int num_yuv_planes = 0;
  381. unsigned int current_pipe = 0;
  382. unsigned int i;
  383. DRM_DEBUG_DRIVER("Starting checking our planes\n");
  384. if (!crtc_state->planes_changed)
  385. return 0;
  386. drm_for_each_plane_mask(plane, drm, crtc_state->plane_mask) {
  387. struct drm_plane_state *plane_state =
  388. drm_atomic_get_plane_state(state, plane);
  389. struct sun4i_layer_state *layer_state =
  390. state_to_sun4i_layer_state(plane_state);
  391. struct drm_framebuffer *fb = plane_state->fb;
  392. struct drm_format_name_buf format_name;
  393. if (sun4i_backend_plane_uses_frontend(plane_state)) {
  394. DRM_DEBUG_DRIVER("Using the frontend for plane %d\n",
  395. plane->index);
  396. layer_state->uses_frontend = true;
  397. num_frontend_planes++;
  398. } else {
  399. layer_state->uses_frontend = false;
  400. }
  401. DRM_DEBUG_DRIVER("Plane FB format is %s\n",
  402. drm_get_format_name(fb->format->format,
  403. &format_name));
  404. if (fb->format->has_alpha)
  405. num_alpha_planes++;
  406. if (sun4i_backend_format_is_yuv(fb->format->format)) {
  407. DRM_DEBUG_DRIVER("Plane FB format is YUV\n");
  408. num_yuv_planes++;
  409. }
  410. DRM_DEBUG_DRIVER("Plane zpos is %d\n",
  411. plane_state->normalized_zpos);
  412. /* Sort our planes by Zpos */
  413. plane_states[plane_state->normalized_zpos] = plane_state;
  414. num_planes++;
  415. }
  416. /* All our planes were disabled, bail out */
  417. if (!num_planes)
  418. return 0;
  419. /*
  420. * The hardware is a bit unusual here.
  421. *
  422. * Even though it supports 4 layers, it does the composition
  423. * in two separate steps.
  424. *
  425. * The first one is assigning a layer to one of its two
  426. * pipes. If more that 1 layer is assigned to the same pipe,
  427. * and if pixels overlaps, the pipe will take the pixel from
  428. * the layer with the highest priority.
  429. *
  430. * The second step is the actual alpha blending, that takes
  431. * the two pipes as input, and uses the eventual alpha
  432. * component to do the transparency between the two.
  433. *
  434. * This two steps scenario makes us unable to guarantee a
  435. * robust alpha blending between the 4 layers in all
  436. * situations, since this means that we need to have one layer
  437. * with alpha at the lowest position of our two pipes.
  438. *
  439. * However, we cannot even do that, since the hardware has a
  440. * bug where the lowest plane of the lowest pipe (pipe 0,
  441. * priority 0), if it has any alpha, will discard the pixel
  442. * entirely and just display the pixels in the background
  443. * color (black by default).
  444. *
  445. * This means that we effectively have only three valid
  446. * configurations with alpha, all of them with the alpha being
  447. * on pipe1 with the lowest position, which can be 1, 2 or 3
  448. * depending on the number of planes and their zpos.
  449. */
  450. if (num_alpha_planes > SUN4I_BACKEND_NUM_ALPHA_LAYERS) {
  451. DRM_DEBUG_DRIVER("Too many planes with alpha, rejecting...\n");
  452. return -EINVAL;
  453. }
  454. /* We can't have an alpha plane at the lowest position */
  455. if (plane_states[0]->fb->format->has_alpha)
  456. return -EINVAL;
  457. for (i = 1; i < num_planes; i++) {
  458. struct drm_plane_state *p_state = plane_states[i];
  459. struct drm_framebuffer *fb = p_state->fb;
  460. struct sun4i_layer_state *s_state = state_to_sun4i_layer_state(p_state);
  461. /*
  462. * The only alpha position is the lowest plane of the
  463. * second pipe.
  464. */
  465. if (fb->format->has_alpha)
  466. current_pipe++;
  467. s_state->pipe = current_pipe;
  468. }
  469. /* We can only have a single YUV plane at a time */
  470. if (num_yuv_planes > SUN4I_BACKEND_NUM_YUV_PLANES) {
  471. DRM_DEBUG_DRIVER("Too many planes with YUV, rejecting...\n");
  472. return -EINVAL;
  473. }
  474. if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) {
  475. DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n");
  476. return -EINVAL;
  477. }
  478. DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video, %u YUV\n",
  479. num_planes, num_alpha_planes, num_frontend_planes,
  480. num_yuv_planes);
  481. return 0;
  482. }
  483. static void sun4i_backend_vblank_quirk(struct sunxi_engine *engine)
  484. {
  485. struct sun4i_backend *backend = engine_to_sun4i_backend(engine);
  486. struct sun4i_frontend *frontend = backend->frontend;
  487. if (!frontend)
  488. return;
  489. /*
  490. * In a teardown scenario with the frontend involved, we have
  491. * to keep the frontend enabled until the next vblank, and
  492. * only then disable it.
  493. *
  494. * This is due to the fact that the backend will not take into
  495. * account the new configuration (with the plane that used to
  496. * be fed by the frontend now disabled) until we write to the
  497. * commit bit and the hardware fetches the new configuration
  498. * during the next vblank.
  499. *
  500. * So we keep the frontend around in order to prevent any
  501. * visual artifacts.
  502. */
  503. spin_lock(&backend->frontend_lock);
  504. if (backend->frontend_teardown) {
  505. sun4i_frontend_exit(frontend);
  506. backend->frontend_teardown = false;
  507. }
  508. spin_unlock(&backend->frontend_lock);
  509. };
  510. static int sun4i_backend_init_sat(struct device *dev) {
  511. struct sun4i_backend *backend = dev_get_drvdata(dev);
  512. int ret;
  513. backend->sat_reset = devm_reset_control_get(dev, "sat");
  514. if (IS_ERR(backend->sat_reset)) {
  515. dev_err(dev, "Couldn't get the SAT reset line\n");
  516. return PTR_ERR(backend->sat_reset);
  517. }
  518. ret = reset_control_deassert(backend->sat_reset);
  519. if (ret) {
  520. dev_err(dev, "Couldn't deassert the SAT reset line\n");
  521. return ret;
  522. }
  523. backend->sat_clk = devm_clk_get(dev, "sat");
  524. if (IS_ERR(backend->sat_clk)) {
  525. dev_err(dev, "Couldn't get our SAT clock\n");
  526. ret = PTR_ERR(backend->sat_clk);
  527. goto err_assert_reset;
  528. }
  529. ret = clk_prepare_enable(backend->sat_clk);
  530. if (ret) {
  531. dev_err(dev, "Couldn't enable the SAT clock\n");
  532. return ret;
  533. }
  534. return 0;
  535. err_assert_reset:
  536. reset_control_assert(backend->sat_reset);
  537. return ret;
  538. }
  539. static int sun4i_backend_free_sat(struct device *dev) {
  540. struct sun4i_backend *backend = dev_get_drvdata(dev);
  541. clk_disable_unprepare(backend->sat_clk);
  542. reset_control_assert(backend->sat_reset);
  543. return 0;
  544. }
  545. /*
  546. * The display backend can take video output from the display frontend, or
  547. * the display enhancement unit on the A80, as input for one it its layers.
  548. * This relationship within the display pipeline is encoded in the device
  549. * tree with of_graph, and we use it here to figure out which backend, if
  550. * there are 2 or more, we are currently probing. The number would be in
  551. * the "reg" property of the upstream output port endpoint.
  552. */
  553. static int sun4i_backend_of_get_id(struct device_node *node)
  554. {
  555. struct device_node *port, *ep;
  556. int ret = -EINVAL;
  557. /* input is port 0 */
  558. port = of_graph_get_port_by_id(node, 0);
  559. if (!port)
  560. return -EINVAL;
  561. /* try finding an upstream endpoint */
  562. for_each_available_child_of_node(port, ep) {
  563. struct device_node *remote;
  564. u32 reg;
  565. remote = of_graph_get_remote_endpoint(ep);
  566. if (!remote)
  567. continue;
  568. ret = of_property_read_u32(remote, "reg", &reg);
  569. if (ret)
  570. continue;
  571. ret = reg;
  572. }
  573. of_node_put(port);
  574. return ret;
  575. }
  576. /* TODO: This needs to take multiple pipelines into account */
  577. static struct sun4i_frontend *sun4i_backend_find_frontend(struct sun4i_drv *drv,
  578. struct device_node *node)
  579. {
  580. struct device_node *port, *ep, *remote;
  581. struct sun4i_frontend *frontend;
  582. port = of_graph_get_port_by_id(node, 0);
  583. if (!port)
  584. return ERR_PTR(-EINVAL);
  585. for_each_available_child_of_node(port, ep) {
  586. remote = of_graph_get_remote_port_parent(ep);
  587. if (!remote)
  588. continue;
  589. /* does this node match any registered engines? */
  590. list_for_each_entry(frontend, &drv->frontend_list, list) {
  591. if (remote == frontend->node) {
  592. of_node_put(remote);
  593. of_node_put(port);
  594. return frontend;
  595. }
  596. }
  597. }
  598. return ERR_PTR(-EINVAL);
  599. }
  600. static const struct sunxi_engine_ops sun4i_backend_engine_ops = {
  601. .atomic_begin = sun4i_backend_atomic_begin,
  602. .atomic_check = sun4i_backend_atomic_check,
  603. .commit = sun4i_backend_commit,
  604. .layers_init = sun4i_layers_init,
  605. .apply_color_correction = sun4i_backend_apply_color_correction,
  606. .disable_color_correction = sun4i_backend_disable_color_correction,
  607. .vblank_quirk = sun4i_backend_vblank_quirk,
  608. };
  609. static struct regmap_config sun4i_backend_regmap_config = {
  610. .reg_bits = 32,
  611. .val_bits = 32,
  612. .reg_stride = 4,
  613. .max_register = 0x5800,
  614. };
  615. static int sun4i_backend_bind(struct device *dev, struct device *master,
  616. void *data)
  617. {
  618. struct platform_device *pdev = to_platform_device(dev);
  619. struct drm_device *drm = data;
  620. struct sun4i_drv *drv = drm->dev_private;
  621. struct sun4i_backend *backend;
  622. const struct sun4i_backend_quirks *quirks;
  623. struct resource *res;
  624. void __iomem *regs;
  625. int i, ret;
  626. backend = devm_kzalloc(dev, sizeof(*backend), GFP_KERNEL);
  627. if (!backend)
  628. return -ENOMEM;
  629. dev_set_drvdata(dev, backend);
  630. spin_lock_init(&backend->frontend_lock);
  631. backend->engine.node = dev->of_node;
  632. backend->engine.ops = &sun4i_backend_engine_ops;
  633. backend->engine.id = sun4i_backend_of_get_id(dev->of_node);
  634. if (backend->engine.id < 0)
  635. return backend->engine.id;
  636. backend->frontend = sun4i_backend_find_frontend(drv, dev->of_node);
  637. if (IS_ERR(backend->frontend))
  638. dev_warn(dev, "Couldn't find matching frontend, frontend features disabled\n");
  639. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  640. regs = devm_ioremap_resource(dev, res);
  641. if (IS_ERR(regs))
  642. return PTR_ERR(regs);
  643. backend->reset = devm_reset_control_get(dev, NULL);
  644. if (IS_ERR(backend->reset)) {
  645. dev_err(dev, "Couldn't get our reset line\n");
  646. return PTR_ERR(backend->reset);
  647. }
  648. ret = reset_control_deassert(backend->reset);
  649. if (ret) {
  650. dev_err(dev, "Couldn't deassert our reset line\n");
  651. return ret;
  652. }
  653. backend->bus_clk = devm_clk_get(dev, "ahb");
  654. if (IS_ERR(backend->bus_clk)) {
  655. dev_err(dev, "Couldn't get the backend bus clock\n");
  656. ret = PTR_ERR(backend->bus_clk);
  657. goto err_assert_reset;
  658. }
  659. clk_prepare_enable(backend->bus_clk);
  660. backend->mod_clk = devm_clk_get(dev, "mod");
  661. if (IS_ERR(backend->mod_clk)) {
  662. dev_err(dev, "Couldn't get the backend module clock\n");
  663. ret = PTR_ERR(backend->mod_clk);
  664. goto err_disable_bus_clk;
  665. }
  666. clk_prepare_enable(backend->mod_clk);
  667. backend->ram_clk = devm_clk_get(dev, "ram");
  668. if (IS_ERR(backend->ram_clk)) {
  669. dev_err(dev, "Couldn't get the backend RAM clock\n");
  670. ret = PTR_ERR(backend->ram_clk);
  671. goto err_disable_mod_clk;
  672. }
  673. clk_prepare_enable(backend->ram_clk);
  674. if (of_device_is_compatible(dev->of_node,
  675. "allwinner,sun8i-a33-display-backend")) {
  676. ret = sun4i_backend_init_sat(dev);
  677. if (ret) {
  678. dev_err(dev, "Couldn't init SAT resources\n");
  679. goto err_disable_ram_clk;
  680. }
  681. }
  682. backend->engine.regs = devm_regmap_init_mmio(dev, regs,
  683. &sun4i_backend_regmap_config);
  684. if (IS_ERR(backend->engine.regs)) {
  685. dev_err(dev, "Couldn't create the backend regmap\n");
  686. return PTR_ERR(backend->engine.regs);
  687. }
  688. list_add_tail(&backend->engine.list, &drv->engine_list);
  689. /*
  690. * Many of the backend's layer configuration registers have
  691. * undefined default values. This poses a risk as we use
  692. * regmap_update_bits in some places, and don't overwrite
  693. * the whole register.
  694. *
  695. * Clear the registers here to have something predictable.
  696. */
  697. for (i = 0x800; i < 0x1000; i += 4)
  698. regmap_write(backend->engine.regs, i, 0);
  699. /* Disable registers autoloading */
  700. regmap_write(backend->engine.regs, SUN4I_BACKEND_REGBUFFCTL_REG,
  701. SUN4I_BACKEND_REGBUFFCTL_AUTOLOAD_DIS);
  702. /* Enable the backend */
  703. regmap_write(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG,
  704. SUN4I_BACKEND_MODCTL_DEBE_EN |
  705. SUN4I_BACKEND_MODCTL_START_CTL);
  706. /* Set output selection if needed */
  707. quirks = of_device_get_match_data(dev);
  708. if (quirks->needs_output_muxing) {
  709. /*
  710. * We assume there is no dynamic muxing of backends
  711. * and TCONs, so we select the backend with same ID.
  712. *
  713. * While dynamic selection might be interesting, since
  714. * the CRTC is tied to the TCON, while the layers are
  715. * tied to the backends, this means, we will need to
  716. * switch between groups of layers. There might not be
  717. * a way to represent this constraint in DRM.
  718. */
  719. regmap_update_bits(backend->engine.regs,
  720. SUN4I_BACKEND_MODCTL_REG,
  721. SUN4I_BACKEND_MODCTL_OUT_SEL,
  722. (backend->engine.id
  723. ? SUN4I_BACKEND_MODCTL_OUT_LCD1
  724. : SUN4I_BACKEND_MODCTL_OUT_LCD0));
  725. }
  726. return 0;
  727. err_disable_ram_clk:
  728. clk_disable_unprepare(backend->ram_clk);
  729. err_disable_mod_clk:
  730. clk_disable_unprepare(backend->mod_clk);
  731. err_disable_bus_clk:
  732. clk_disable_unprepare(backend->bus_clk);
  733. err_assert_reset:
  734. reset_control_assert(backend->reset);
  735. return ret;
  736. }
  737. static void sun4i_backend_unbind(struct device *dev, struct device *master,
  738. void *data)
  739. {
  740. struct sun4i_backend *backend = dev_get_drvdata(dev);
  741. list_del(&backend->engine.list);
  742. if (of_device_is_compatible(dev->of_node,
  743. "allwinner,sun8i-a33-display-backend"))
  744. sun4i_backend_free_sat(dev);
  745. clk_disable_unprepare(backend->ram_clk);
  746. clk_disable_unprepare(backend->mod_clk);
  747. clk_disable_unprepare(backend->bus_clk);
  748. reset_control_assert(backend->reset);
  749. }
  750. static const struct component_ops sun4i_backend_ops = {
  751. .bind = sun4i_backend_bind,
  752. .unbind = sun4i_backend_unbind,
  753. };
  754. static int sun4i_backend_probe(struct platform_device *pdev)
  755. {
  756. return component_add(&pdev->dev, &sun4i_backend_ops);
  757. }
  758. static int sun4i_backend_remove(struct platform_device *pdev)
  759. {
  760. component_del(&pdev->dev, &sun4i_backend_ops);
  761. return 0;
  762. }
  763. static const struct sun4i_backend_quirks sun4i_backend_quirks = {
  764. .needs_output_muxing = true,
  765. };
  766. static const struct sun4i_backend_quirks sun5i_backend_quirks = {
  767. };
  768. static const struct sun4i_backend_quirks sun6i_backend_quirks = {
  769. };
  770. static const struct sun4i_backend_quirks sun7i_backend_quirks = {
  771. .needs_output_muxing = true,
  772. };
  773. static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
  774. };
  775. static const struct sun4i_backend_quirks sun9i_backend_quirks = {
  776. };
  777. static const struct of_device_id sun4i_backend_of_table[] = {
  778. {
  779. .compatible = "allwinner,sun4i-a10-display-backend",
  780. .data = &sun4i_backend_quirks,
  781. },
  782. {
  783. .compatible = "allwinner,sun5i-a13-display-backend",
  784. .data = &sun5i_backend_quirks,
  785. },
  786. {
  787. .compatible = "allwinner,sun6i-a31-display-backend",
  788. .data = &sun6i_backend_quirks,
  789. },
  790. {
  791. .compatible = "allwinner,sun7i-a20-display-backend",
  792. .data = &sun7i_backend_quirks,
  793. },
  794. {
  795. .compatible = "allwinner,sun8i-a33-display-backend",
  796. .data = &sun8i_a33_backend_quirks,
  797. },
  798. {
  799. .compatible = "allwinner,sun9i-a80-display-backend",
  800. .data = &sun9i_backend_quirks,
  801. },
  802. { }
  803. };
  804. MODULE_DEVICE_TABLE(of, sun4i_backend_of_table);
  805. static struct platform_driver sun4i_backend_platform_driver = {
  806. .probe = sun4i_backend_probe,
  807. .remove = sun4i_backend_remove,
  808. .driver = {
  809. .name = "sun4i-backend",
  810. .of_match_table = sun4i_backend_of_table,
  811. },
  812. };
  813. module_platform_driver(sun4i_backend_platform_driver);
  814. MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
  815. MODULE_DESCRIPTION("Allwinner A10 Display Backend Driver");
  816. MODULE_LICENSE("GPL");