sun4i_backend.c 27 KB

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