sun4i_tcon.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  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_helper.h>
  14. #include <drm/drm_crtc.h>
  15. #include <drm/drm_crtc_helper.h>
  16. #include <drm/drm_encoder.h>
  17. #include <drm/drm_modes.h>
  18. #include <drm/drm_of.h>
  19. #include <uapi/drm/drm_mode.h>
  20. #include <linux/component.h>
  21. #include <linux/ioport.h>
  22. #include <linux/of_address.h>
  23. #include <linux/of_device.h>
  24. #include <linux/of_irq.h>
  25. #include <linux/regmap.h>
  26. #include <linux/reset.h>
  27. #include "sun4i_crtc.h"
  28. #include "sun4i_dotclock.h"
  29. #include "sun4i_drv.h"
  30. #include "sun4i_rgb.h"
  31. #include "sun4i_tcon.h"
  32. #include "sunxi_engine.h"
  33. static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
  34. bool enabled)
  35. {
  36. struct clk *clk;
  37. switch (channel) {
  38. case 0:
  39. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  40. SUN4I_TCON0_CTL_TCON_ENABLE,
  41. enabled ? SUN4I_TCON0_CTL_TCON_ENABLE : 0);
  42. clk = tcon->dclk;
  43. break;
  44. case 1:
  45. WARN_ON(!tcon->quirks->has_channel_1);
  46. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  47. SUN4I_TCON1_CTL_TCON_ENABLE,
  48. enabled ? SUN4I_TCON1_CTL_TCON_ENABLE : 0);
  49. clk = tcon->sclk1;
  50. break;
  51. default:
  52. DRM_WARN("Unknown channel... doing nothing\n");
  53. return;
  54. }
  55. if (enabled)
  56. clk_prepare_enable(clk);
  57. else
  58. clk_disable_unprepare(clk);
  59. }
  60. void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
  61. const struct drm_encoder *encoder,
  62. bool enabled)
  63. {
  64. int channel;
  65. switch (encoder->encoder_type) {
  66. case DRM_MODE_ENCODER_NONE:
  67. channel = 0;
  68. break;
  69. case DRM_MODE_ENCODER_TMDS:
  70. case DRM_MODE_ENCODER_TVDAC:
  71. channel = 1;
  72. break;
  73. default:
  74. DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
  75. return;
  76. }
  77. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  78. SUN4I_TCON_GCTL_TCON_ENABLE,
  79. enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
  80. sun4i_tcon_channel_set_status(tcon, channel, enabled);
  81. }
  82. void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
  83. {
  84. u32 mask, val = 0;
  85. DRM_DEBUG_DRIVER("%sabling VBLANK interrupt\n", enable ? "En" : "Dis");
  86. mask = SUN4I_TCON_GINT0_VBLANK_ENABLE(0) |
  87. SUN4I_TCON_GINT0_VBLANK_ENABLE(1);
  88. if (enable)
  89. val = mask;
  90. regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, mask, val);
  91. }
  92. EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
  93. /*
  94. * This function is a helper for TCON output muxing. The TCON output
  95. * muxing control register in earlier SoCs (without the TCON TOP block)
  96. * are located in TCON0. This helper returns a pointer to TCON0's
  97. * sun4i_tcon structure, or NULL if not found.
  98. */
  99. static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
  100. {
  101. struct sun4i_drv *drv = drm->dev_private;
  102. struct sun4i_tcon *tcon;
  103. list_for_each_entry(tcon, &drv->tcon_list, list)
  104. if (tcon->id == 0)
  105. return tcon;
  106. dev_warn(drm->dev,
  107. "TCON0 not found, display output muxing may not work\n");
  108. return NULL;
  109. }
  110. void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
  111. const struct drm_encoder *encoder)
  112. {
  113. int ret = -ENOTSUPP;
  114. if (tcon->quirks->set_mux)
  115. ret = tcon->quirks->set_mux(tcon, encoder);
  116. DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
  117. encoder->name, encoder->crtc->name, ret);
  118. }
  119. static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode,
  120. int channel)
  121. {
  122. int delay = mode->vtotal - mode->vdisplay;
  123. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  124. delay /= 2;
  125. if (channel == 1)
  126. delay -= 2;
  127. delay = min(delay, 30);
  128. DRM_DEBUG_DRIVER("TCON %d clock delay %u\n", channel, delay);
  129. return delay;
  130. }
  131. static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
  132. const struct drm_display_mode *mode)
  133. {
  134. /* Configure the dot clock */
  135. clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
  136. /* Set the resolution */
  137. regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
  138. SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
  139. SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
  140. }
  141. static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
  142. const struct drm_display_mode *mode)
  143. {
  144. unsigned int bp, hsync, vsync;
  145. u8 clk_delay;
  146. u32 val = 0;
  147. sun4i_tcon0_mode_set_common(tcon, mode);
  148. /* Adjust clock delay */
  149. clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
  150. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  151. SUN4I_TCON0_CTL_CLK_DELAY_MASK,
  152. SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
  153. /*
  154. * This is called a backporch in the register documentation,
  155. * but it really is the back porch + hsync
  156. */
  157. bp = mode->crtc_htotal - mode->crtc_hsync_start;
  158. DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
  159. mode->crtc_htotal, bp);
  160. /* Set horizontal display timings */
  161. regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
  162. SUN4I_TCON0_BASIC1_H_TOTAL(mode->crtc_htotal) |
  163. SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
  164. /*
  165. * This is called a backporch in the register documentation,
  166. * but it really is the back porch + hsync
  167. */
  168. bp = mode->crtc_vtotal - mode->crtc_vsync_start;
  169. DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
  170. mode->crtc_vtotal, bp);
  171. /* Set vertical display timings */
  172. regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
  173. SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
  174. SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
  175. /* Set Hsync and Vsync length */
  176. hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
  177. vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
  178. DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync);
  179. regmap_write(tcon->regs, SUN4I_TCON0_BASIC3_REG,
  180. SUN4I_TCON0_BASIC3_V_SYNC(vsync) |
  181. SUN4I_TCON0_BASIC3_H_SYNC(hsync));
  182. /* Setup the polarity of the various signals */
  183. if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
  184. val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
  185. if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
  186. val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
  187. regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
  188. SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE,
  189. val);
  190. /* Map output pins to channel 0 */
  191. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  192. SUN4I_TCON_GCTL_IOMAP_MASK,
  193. SUN4I_TCON_GCTL_IOMAP_TCON0);
  194. /* Enable the output on the pins */
  195. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0);
  196. }
  197. static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
  198. const struct drm_display_mode *mode)
  199. {
  200. unsigned int bp, hsync, vsync, vtotal;
  201. u8 clk_delay;
  202. u32 val;
  203. WARN_ON(!tcon->quirks->has_channel_1);
  204. /* Configure the dot clock */
  205. clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
  206. /* Adjust clock delay */
  207. clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
  208. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  209. SUN4I_TCON1_CTL_CLK_DELAY_MASK,
  210. SUN4I_TCON1_CTL_CLK_DELAY(clk_delay));
  211. /* Set interlaced mode */
  212. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  213. val = SUN4I_TCON1_CTL_INTERLACE_ENABLE;
  214. else
  215. val = 0;
  216. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  217. SUN4I_TCON1_CTL_INTERLACE_ENABLE,
  218. val);
  219. /* Set the input resolution */
  220. regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG,
  221. SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) |
  222. SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay));
  223. /* Set the upscaling resolution */
  224. regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG,
  225. SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) |
  226. SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay));
  227. /* Set the output resolution */
  228. regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG,
  229. SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) |
  230. SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay));
  231. /* Set horizontal display timings */
  232. bp = mode->crtc_htotal - mode->crtc_hsync_start;
  233. DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
  234. mode->htotal, bp);
  235. regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG,
  236. SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) |
  237. SUN4I_TCON1_BASIC3_H_BACKPORCH(bp));
  238. bp = mode->crtc_vtotal - mode->crtc_vsync_start;
  239. DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
  240. mode->crtc_vtotal, bp);
  241. /*
  242. * The vertical resolution needs to be doubled in all
  243. * cases. We could use crtc_vtotal and always multiply by two,
  244. * but that leads to a rounding error in interlace when vtotal
  245. * is odd.
  246. *
  247. * This happens with TV's PAL for example, where vtotal will
  248. * be 625, crtc_vtotal 312, and thus crtc_vtotal * 2 will be
  249. * 624, which apparently confuses the hardware.
  250. *
  251. * To work around this, we will always use vtotal, and
  252. * multiply by two only if we're not in interlace.
  253. */
  254. vtotal = mode->vtotal;
  255. if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
  256. vtotal = vtotal * 2;
  257. /* Set vertical display timings */
  258. regmap_write(tcon->regs, SUN4I_TCON1_BASIC4_REG,
  259. SUN4I_TCON1_BASIC4_V_TOTAL(vtotal) |
  260. SUN4I_TCON1_BASIC4_V_BACKPORCH(bp));
  261. /* Set Hsync and Vsync length */
  262. hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
  263. vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
  264. DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync);
  265. regmap_write(tcon->regs, SUN4I_TCON1_BASIC5_REG,
  266. SUN4I_TCON1_BASIC5_V_SYNC(vsync) |
  267. SUN4I_TCON1_BASIC5_H_SYNC(hsync));
  268. /* Map output pins to channel 1 */
  269. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  270. SUN4I_TCON_GCTL_IOMAP_MASK,
  271. SUN4I_TCON_GCTL_IOMAP_TCON1);
  272. }
  273. void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
  274. const struct drm_encoder *encoder,
  275. const struct drm_display_mode *mode)
  276. {
  277. switch (encoder->encoder_type) {
  278. case DRM_MODE_ENCODER_NONE:
  279. sun4i_tcon0_mode_set_rgb(tcon, mode);
  280. sun4i_tcon_set_mux(tcon, 0, encoder);
  281. break;
  282. case DRM_MODE_ENCODER_TVDAC:
  283. case DRM_MODE_ENCODER_TMDS:
  284. sun4i_tcon1_mode_set(tcon, mode);
  285. sun4i_tcon_set_mux(tcon, 1, encoder);
  286. break;
  287. default:
  288. DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
  289. }
  290. }
  291. EXPORT_SYMBOL(sun4i_tcon_mode_set);
  292. static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
  293. struct sun4i_crtc *scrtc)
  294. {
  295. unsigned long flags;
  296. spin_lock_irqsave(&dev->event_lock, flags);
  297. if (scrtc->event) {
  298. drm_crtc_send_vblank_event(&scrtc->crtc, scrtc->event);
  299. drm_crtc_vblank_put(&scrtc->crtc);
  300. scrtc->event = NULL;
  301. }
  302. spin_unlock_irqrestore(&dev->event_lock, flags);
  303. }
  304. static irqreturn_t sun4i_tcon_handler(int irq, void *private)
  305. {
  306. struct sun4i_tcon *tcon = private;
  307. struct drm_device *drm = tcon->drm;
  308. struct sun4i_crtc *scrtc = tcon->crtc;
  309. unsigned int status;
  310. regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status);
  311. if (!(status & (SUN4I_TCON_GINT0_VBLANK_INT(0) |
  312. SUN4I_TCON_GINT0_VBLANK_INT(1))))
  313. return IRQ_NONE;
  314. drm_crtc_handle_vblank(&scrtc->crtc);
  315. sun4i_tcon_finish_page_flip(drm, scrtc);
  316. /* Acknowledge the interrupt */
  317. regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
  318. SUN4I_TCON_GINT0_VBLANK_INT(0) |
  319. SUN4I_TCON_GINT0_VBLANK_INT(1),
  320. 0);
  321. return IRQ_HANDLED;
  322. }
  323. static int sun4i_tcon_init_clocks(struct device *dev,
  324. struct sun4i_tcon *tcon)
  325. {
  326. tcon->clk = devm_clk_get(dev, "ahb");
  327. if (IS_ERR(tcon->clk)) {
  328. dev_err(dev, "Couldn't get the TCON bus clock\n");
  329. return PTR_ERR(tcon->clk);
  330. }
  331. clk_prepare_enable(tcon->clk);
  332. tcon->sclk0 = devm_clk_get(dev, "tcon-ch0");
  333. if (IS_ERR(tcon->sclk0)) {
  334. dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
  335. return PTR_ERR(tcon->sclk0);
  336. }
  337. if (tcon->quirks->has_channel_1) {
  338. tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
  339. if (IS_ERR(tcon->sclk1)) {
  340. dev_err(dev, "Couldn't get the TCON channel 1 clock\n");
  341. return PTR_ERR(tcon->sclk1);
  342. }
  343. }
  344. return 0;
  345. }
  346. static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon)
  347. {
  348. clk_disable_unprepare(tcon->clk);
  349. }
  350. static int sun4i_tcon_init_irq(struct device *dev,
  351. struct sun4i_tcon *tcon)
  352. {
  353. struct platform_device *pdev = to_platform_device(dev);
  354. int irq, ret;
  355. irq = platform_get_irq(pdev, 0);
  356. if (irq < 0) {
  357. dev_err(dev, "Couldn't retrieve the TCON interrupt\n");
  358. return irq;
  359. }
  360. ret = devm_request_irq(dev, irq, sun4i_tcon_handler, 0,
  361. dev_name(dev), tcon);
  362. if (ret) {
  363. dev_err(dev, "Couldn't request the IRQ\n");
  364. return ret;
  365. }
  366. return 0;
  367. }
  368. static struct regmap_config sun4i_tcon_regmap_config = {
  369. .reg_bits = 32,
  370. .val_bits = 32,
  371. .reg_stride = 4,
  372. .max_register = 0x800,
  373. };
  374. static int sun4i_tcon_init_regmap(struct device *dev,
  375. struct sun4i_tcon *tcon)
  376. {
  377. struct platform_device *pdev = to_platform_device(dev);
  378. struct resource *res;
  379. void __iomem *regs;
  380. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  381. regs = devm_ioremap_resource(dev, res);
  382. if (IS_ERR(regs))
  383. return PTR_ERR(regs);
  384. tcon->regs = devm_regmap_init_mmio(dev, regs,
  385. &sun4i_tcon_regmap_config);
  386. if (IS_ERR(tcon->regs)) {
  387. dev_err(dev, "Couldn't create the TCON regmap\n");
  388. return PTR_ERR(tcon->regs);
  389. }
  390. /* Make sure the TCON is disabled and all IRQs are off */
  391. regmap_write(tcon->regs, SUN4I_TCON_GCTL_REG, 0);
  392. regmap_write(tcon->regs, SUN4I_TCON_GINT0_REG, 0);
  393. regmap_write(tcon->regs, SUN4I_TCON_GINT1_REG, 0);
  394. /* Disable IO lines and set them to tristate */
  395. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, ~0);
  396. regmap_write(tcon->regs, SUN4I_TCON1_IO_TRI_REG, ~0);
  397. return 0;
  398. }
  399. /*
  400. * On SoCs with the old display pipeline design (Display Engine 1.0),
  401. * the TCON is always tied to just one backend. Hence we can traverse
  402. * the of_graph upwards to find the backend our tcon is connected to,
  403. * and take its ID as our own.
  404. *
  405. * We can either identify backends from their compatible strings, which
  406. * means maintaining a large list of them. Or, since the backend is
  407. * registered and binded before the TCON, we can just go through the
  408. * list of registered backends and compare the device node.
  409. *
  410. * As the structures now store engines instead of backends, here this
  411. * function in fact searches the corresponding engine, and the ID is
  412. * requested via the get_id function of the engine.
  413. */
  414. static struct sunxi_engine *
  415. sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
  416. struct device_node *node)
  417. {
  418. struct device_node *port, *ep, *remote;
  419. struct sunxi_engine *engine = ERR_PTR(-EINVAL);
  420. port = of_graph_get_port_by_id(node, 0);
  421. if (!port)
  422. return ERR_PTR(-EINVAL);
  423. /*
  424. * This only works if there is only one path from the TCON
  425. * to any display engine. Otherwise the probe order of the
  426. * TCONs and display engines is not guaranteed. They may
  427. * either bind to the wrong one, or worse, bind to the same
  428. * one if additional checks are not done.
  429. *
  430. * Bail out if there are multiple input connections.
  431. */
  432. if (of_get_available_child_count(port) != 1)
  433. goto out_put_port;
  434. /* Get the first connection without specifying an ID */
  435. ep = of_get_next_available_child(port, NULL);
  436. if (!ep)
  437. goto out_put_port;
  438. remote = of_graph_get_remote_port_parent(ep);
  439. if (!remote)
  440. goto out_put_ep;
  441. /* does this node match any registered engines? */
  442. list_for_each_entry(engine, &drv->engine_list, list)
  443. if (remote == engine->node)
  444. goto out_put_remote;
  445. /* keep looking through upstream ports */
  446. engine = sun4i_tcon_find_engine_traverse(drv, remote);
  447. out_put_remote:
  448. of_node_put(remote);
  449. out_put_ep:
  450. of_node_put(ep);
  451. out_put_port:
  452. of_node_put(port);
  453. return engine;
  454. }
  455. /*
  456. * The device tree binding says that the remote endpoint ID of any
  457. * connection between components, up to and including the TCON, of
  458. * the display pipeline should be equal to the actual ID of the local
  459. * component. Thus we can look at any one of the input connections of
  460. * the TCONs, and use that connection's remote endpoint ID as our own.
  461. *
  462. * Since the user of this function already finds the input port,
  463. * the port is passed in directly without further checks.
  464. */
  465. static int sun4i_tcon_of_get_id_from_port(struct device_node *port)
  466. {
  467. struct device_node *ep;
  468. int ret = -EINVAL;
  469. /* try finding an upstream endpoint */
  470. for_each_available_child_of_node(port, ep) {
  471. struct device_node *remote;
  472. u32 reg;
  473. remote = of_graph_get_remote_endpoint(ep);
  474. if (!remote)
  475. continue;
  476. ret = of_property_read_u32(remote, "reg", &reg);
  477. if (ret)
  478. continue;
  479. ret = reg;
  480. }
  481. return ret;
  482. }
  483. /*
  484. * Once we know the TCON's id, we can look through the list of
  485. * engines to find a matching one. We assume all engines have
  486. * been probed and added to the list.
  487. */
  488. static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv,
  489. int id)
  490. {
  491. struct sunxi_engine *engine;
  492. list_for_each_entry(engine, &drv->engine_list, list)
  493. if (engine->id == id)
  494. return engine;
  495. return ERR_PTR(-EINVAL);
  496. }
  497. /*
  498. * On SoCs with the old display pipeline design (Display Engine 1.0),
  499. * we assumed the TCON was always tied to just one backend. However
  500. * this proved not to be the case. On the A31, the TCON can select
  501. * either backend as its source. On the A20 (and likely on the A10),
  502. * the backend can choose which TCON to output to.
  503. *
  504. * The device tree binding says that the remote endpoint ID of any
  505. * connection between components, up to and including the TCON, of
  506. * the display pipeline should be equal to the actual ID of the local
  507. * component. Thus we should be able to look at any one of the input
  508. * connections of the TCONs, and use that connection's remote endpoint
  509. * ID as our own.
  510. *
  511. * However the connections between the backend and TCON were assumed
  512. * to be always singular, and their endpoit IDs were all incorrectly
  513. * set to 0. This means for these old device trees, we cannot just look
  514. * up the remote endpoint ID of a TCON input endpoint. TCON1 would be
  515. * incorrectly identified as TCON0.
  516. *
  517. * This function first checks if the TCON node has 2 input endpoints.
  518. * If so, then the device tree is a corrected version, and it will use
  519. * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above
  520. * to fetch the ID and engine directly. If not, then it is likely an
  521. * old device trees, where the endpoint IDs were incorrect, but did not
  522. * have endpoint connections between the backend and TCON across
  523. * different display pipelines. It will fall back to the old method of
  524. * traversing the of_graph to try and find a matching engine by device
  525. * node.
  526. *
  527. * In the case of single display pipeline device trees, either method
  528. * works.
  529. */
  530. static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
  531. struct device_node *node)
  532. {
  533. struct device_node *port;
  534. struct sunxi_engine *engine;
  535. port = of_graph_get_port_by_id(node, 0);
  536. if (!port)
  537. return ERR_PTR(-EINVAL);
  538. /*
  539. * Is this a corrected device tree with cross pipeline
  540. * connections between the backend and TCON?
  541. */
  542. if (of_get_child_count(port) > 1) {
  543. /* Get our ID directly from an upstream endpoint */
  544. int id = sun4i_tcon_of_get_id_from_port(port);
  545. /* Get our engine by matching our ID */
  546. engine = sun4i_tcon_get_engine_by_id(drv, id);
  547. of_node_put(port);
  548. return engine;
  549. }
  550. /* Fallback to old method by traversing input endpoints */
  551. of_node_put(port);
  552. return sun4i_tcon_find_engine_traverse(drv, node);
  553. }
  554. static int sun4i_tcon_bind(struct device *dev, struct device *master,
  555. void *data)
  556. {
  557. struct drm_device *drm = data;
  558. struct sun4i_drv *drv = drm->dev_private;
  559. struct sunxi_engine *engine;
  560. struct sun4i_tcon *tcon;
  561. int ret;
  562. engine = sun4i_tcon_find_engine(drv, dev->of_node);
  563. if (IS_ERR(engine)) {
  564. dev_err(dev, "Couldn't find matching engine\n");
  565. return -EPROBE_DEFER;
  566. }
  567. tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
  568. if (!tcon)
  569. return -ENOMEM;
  570. dev_set_drvdata(dev, tcon);
  571. tcon->drm = drm;
  572. tcon->dev = dev;
  573. tcon->id = engine->id;
  574. tcon->quirks = of_device_get_match_data(dev);
  575. tcon->lcd_rst = devm_reset_control_get(dev, "lcd");
  576. if (IS_ERR(tcon->lcd_rst)) {
  577. dev_err(dev, "Couldn't get our reset line\n");
  578. return PTR_ERR(tcon->lcd_rst);
  579. }
  580. /* Make sure our TCON is reset */
  581. ret = reset_control_reset(tcon->lcd_rst);
  582. if (ret) {
  583. dev_err(dev, "Couldn't deassert our reset line\n");
  584. return ret;
  585. }
  586. ret = sun4i_tcon_init_clocks(dev, tcon);
  587. if (ret) {
  588. dev_err(dev, "Couldn't init our TCON clocks\n");
  589. goto err_assert_reset;
  590. }
  591. ret = sun4i_tcon_init_regmap(dev, tcon);
  592. if (ret) {
  593. dev_err(dev, "Couldn't init our TCON regmap\n");
  594. goto err_free_clocks;
  595. }
  596. ret = sun4i_dclk_create(dev, tcon);
  597. if (ret) {
  598. dev_err(dev, "Couldn't create our TCON dot clock\n");
  599. goto err_free_clocks;
  600. }
  601. ret = sun4i_tcon_init_irq(dev, tcon);
  602. if (ret) {
  603. dev_err(dev, "Couldn't init our TCON interrupts\n");
  604. goto err_free_dotclock;
  605. }
  606. tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
  607. if (IS_ERR(tcon->crtc)) {
  608. dev_err(dev, "Couldn't create our CRTC\n");
  609. ret = PTR_ERR(tcon->crtc);
  610. goto err_free_clocks;
  611. }
  612. ret = sun4i_rgb_init(drm, tcon);
  613. if (ret < 0)
  614. goto err_free_clocks;
  615. if (tcon->quirks->needs_de_be_mux) {
  616. /*
  617. * We assume there is no dynamic muxing of backends
  618. * and TCONs, so we select the backend with same ID.
  619. *
  620. * While dynamic selection might be interesting, since
  621. * the CRTC is tied to the TCON, while the layers are
  622. * tied to the backends, this means, we will need to
  623. * switch between groups of layers. There might not be
  624. * a way to represent this constraint in DRM.
  625. */
  626. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  627. SUN4I_TCON0_CTL_SRC_SEL_MASK,
  628. tcon->id);
  629. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  630. SUN4I_TCON1_CTL_SRC_SEL_MASK,
  631. tcon->id);
  632. }
  633. list_add_tail(&tcon->list, &drv->tcon_list);
  634. return 0;
  635. err_free_dotclock:
  636. sun4i_dclk_free(tcon);
  637. err_free_clocks:
  638. sun4i_tcon_free_clocks(tcon);
  639. err_assert_reset:
  640. reset_control_assert(tcon->lcd_rst);
  641. return ret;
  642. }
  643. static void sun4i_tcon_unbind(struct device *dev, struct device *master,
  644. void *data)
  645. {
  646. struct sun4i_tcon *tcon = dev_get_drvdata(dev);
  647. list_del(&tcon->list);
  648. sun4i_dclk_free(tcon);
  649. sun4i_tcon_free_clocks(tcon);
  650. }
  651. static const struct component_ops sun4i_tcon_ops = {
  652. .bind = sun4i_tcon_bind,
  653. .unbind = sun4i_tcon_unbind,
  654. };
  655. static int sun4i_tcon_probe(struct platform_device *pdev)
  656. {
  657. struct device_node *node = pdev->dev.of_node;
  658. struct drm_bridge *bridge;
  659. struct drm_panel *panel;
  660. int ret;
  661. ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
  662. if (ret == -EPROBE_DEFER)
  663. return ret;
  664. return component_add(&pdev->dev, &sun4i_tcon_ops);
  665. }
  666. static int sun4i_tcon_remove(struct platform_device *pdev)
  667. {
  668. component_del(&pdev->dev, &sun4i_tcon_ops);
  669. return 0;
  670. }
  671. /* platform specific TCON muxing callbacks */
  672. static int sun4i_a10_tcon_set_mux(struct sun4i_tcon *tcon,
  673. const struct drm_encoder *encoder)
  674. {
  675. struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
  676. u32 shift;
  677. if (!tcon0)
  678. return -EINVAL;
  679. switch (encoder->encoder_type) {
  680. case DRM_MODE_ENCODER_TMDS:
  681. /* HDMI */
  682. shift = 8;
  683. break;
  684. default:
  685. return -EINVAL;
  686. }
  687. regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
  688. 0x3 << shift, tcon->id << shift);
  689. return 0;
  690. }
  691. static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
  692. const struct drm_encoder *encoder)
  693. {
  694. u32 val;
  695. if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
  696. val = 1;
  697. else
  698. val = 0;
  699. /*
  700. * FIXME: Undocumented bits
  701. */
  702. return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
  703. }
  704. static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon,
  705. const struct drm_encoder *encoder)
  706. {
  707. struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
  708. u32 shift;
  709. if (!tcon0)
  710. return -EINVAL;
  711. switch (encoder->encoder_type) {
  712. case DRM_MODE_ENCODER_TMDS:
  713. /* HDMI */
  714. shift = 8;
  715. break;
  716. default:
  717. /* TODO A31 has MIPI DSI but A31s does not */
  718. return -EINVAL;
  719. }
  720. regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
  721. 0x3 << shift, tcon->id << shift);
  722. return 0;
  723. }
  724. static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
  725. .has_channel_1 = true,
  726. .set_mux = sun4i_a10_tcon_set_mux,
  727. };
  728. static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
  729. .has_channel_1 = true,
  730. .set_mux = sun5i_a13_tcon_set_mux,
  731. };
  732. static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
  733. .has_channel_1 = true,
  734. .needs_de_be_mux = true,
  735. .set_mux = sun6i_tcon_set_mux,
  736. };
  737. static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
  738. .has_channel_1 = true,
  739. .needs_de_be_mux = true,
  740. };
  741. static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
  742. .has_channel_1 = true,
  743. /* Same display pipeline structure as A10 */
  744. .set_mux = sun4i_a10_tcon_set_mux,
  745. };
  746. static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
  747. /* nothing is supported */
  748. };
  749. static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
  750. /* nothing is supported */
  751. };
  752. /* sun4i_drv uses this list to check if a device node is a TCON */
  753. const struct of_device_id sun4i_tcon_of_table[] = {
  754. { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
  755. { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
  756. { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
  757. { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
  758. { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
  759. { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
  760. { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
  761. { }
  762. };
  763. MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
  764. EXPORT_SYMBOL(sun4i_tcon_of_table);
  765. static struct platform_driver sun4i_tcon_platform_driver = {
  766. .probe = sun4i_tcon_probe,
  767. .remove = sun4i_tcon_remove,
  768. .driver = {
  769. .name = "sun4i-tcon",
  770. .of_match_table = sun4i_tcon_of_table,
  771. },
  772. };
  773. module_platform_driver(sun4i_tcon_platform_driver);
  774. MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
  775. MODULE_DESCRIPTION("Allwinner A10 Timing Controller Driver");
  776. MODULE_LICENSE("GPL");