sun4i_tcon.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2015 Free Electrons
  4. * Copyright (C) 2015 NextThing Co
  5. *
  6. * Maxime Ripard <[email protected]>
  7. */
  8. #include <linux/component.h>
  9. #include <linux/ioport.h>
  10. #include <linux/media-bus-format.h>
  11. #include <linux/module.h>
  12. #include <linux/of_address.h>
  13. #include <linux/of_device.h>
  14. #include <linux/of_irq.h>
  15. #include <linux/regmap.h>
  16. #include <linux/reset.h>
  17. #include <drm/drm_atomic_helper.h>
  18. #include <drm/drm_bridge.h>
  19. #include <drm/drm_connector.h>
  20. #include <drm/drm_crtc.h>
  21. #include <drm/drm_encoder.h>
  22. #include <drm/drm_modes.h>
  23. #include <drm/drm_of.h>
  24. #include <drm/drm_panel.h>
  25. #include <drm/drm_print.h>
  26. #include <drm/drm_probe_helper.h>
  27. #include <drm/drm_vblank.h>
  28. #include <uapi/drm/drm_mode.h>
  29. #include "sun4i_crtc.h"
  30. #include "sun4i_dotclock.h"
  31. #include "sun4i_drv.h"
  32. #include "sun4i_lvds.h"
  33. #include "sun4i_rgb.h"
  34. #include "sun4i_tcon.h"
  35. #include "sun6i_mipi_dsi.h"
  36. #include "sun8i_tcon_top.h"
  37. #include "sunxi_engine.h"
  38. static struct drm_connector *sun4i_tcon_get_connector(const struct drm_encoder *encoder)
  39. {
  40. struct drm_connector *connector;
  41. struct drm_connector_list_iter iter;
  42. drm_connector_list_iter_begin(encoder->dev, &iter);
  43. drm_for_each_connector_iter(connector, &iter)
  44. if (connector->encoder == encoder) {
  45. drm_connector_list_iter_end(&iter);
  46. return connector;
  47. }
  48. drm_connector_list_iter_end(&iter);
  49. return NULL;
  50. }
  51. static int sun4i_tcon_get_pixel_depth(const struct drm_encoder *encoder)
  52. {
  53. struct drm_connector *connector;
  54. struct drm_display_info *info;
  55. connector = sun4i_tcon_get_connector(encoder);
  56. if (!connector)
  57. return -EINVAL;
  58. info = &connector->display_info;
  59. if (info->num_bus_formats != 1)
  60. return -EINVAL;
  61. switch (info->bus_formats[0]) {
  62. case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
  63. return 18;
  64. case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
  65. case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
  66. return 24;
  67. }
  68. return -EINVAL;
  69. }
  70. static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
  71. bool enabled)
  72. {
  73. struct clk *clk;
  74. switch (channel) {
  75. case 0:
  76. WARN_ON(!tcon->quirks->has_channel_0);
  77. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  78. SUN4I_TCON0_CTL_TCON_ENABLE,
  79. enabled ? SUN4I_TCON0_CTL_TCON_ENABLE : 0);
  80. clk = tcon->dclk;
  81. break;
  82. case 1:
  83. WARN_ON(!tcon->quirks->has_channel_1);
  84. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  85. SUN4I_TCON1_CTL_TCON_ENABLE,
  86. enabled ? SUN4I_TCON1_CTL_TCON_ENABLE : 0);
  87. clk = tcon->sclk1;
  88. break;
  89. default:
  90. DRM_WARN("Unknown channel... doing nothing\n");
  91. return;
  92. }
  93. if (enabled) {
  94. clk_prepare_enable(clk);
  95. clk_rate_exclusive_get(clk);
  96. } else {
  97. clk_rate_exclusive_put(clk);
  98. clk_disable_unprepare(clk);
  99. }
  100. }
  101. static void sun4i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
  102. const struct drm_encoder *encoder)
  103. {
  104. regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
  105. SUN4I_TCON0_LVDS_ANA0_CK_EN |
  106. SUN4I_TCON0_LVDS_ANA0_REG_V |
  107. SUN4I_TCON0_LVDS_ANA0_REG_C |
  108. SUN4I_TCON0_LVDS_ANA0_EN_MB |
  109. SUN4I_TCON0_LVDS_ANA0_PD |
  110. SUN4I_TCON0_LVDS_ANA0_DCHS);
  111. udelay(2); /* delay at least 1200 ns */
  112. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
  113. SUN4I_TCON0_LVDS_ANA1_INIT,
  114. SUN4I_TCON0_LVDS_ANA1_INIT);
  115. udelay(1); /* delay at least 120 ns */
  116. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA1_REG,
  117. SUN4I_TCON0_LVDS_ANA1_UPDATE,
  118. SUN4I_TCON0_LVDS_ANA1_UPDATE);
  119. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
  120. SUN4I_TCON0_LVDS_ANA0_EN_MB,
  121. SUN4I_TCON0_LVDS_ANA0_EN_MB);
  122. }
  123. static void sun6i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
  124. const struct drm_encoder *encoder)
  125. {
  126. u8 val;
  127. regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
  128. SUN6I_TCON0_LVDS_ANA0_C(2) |
  129. SUN6I_TCON0_LVDS_ANA0_V(3) |
  130. SUN6I_TCON0_LVDS_ANA0_PD(2) |
  131. SUN6I_TCON0_LVDS_ANA0_EN_LDO);
  132. udelay(2);
  133. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
  134. SUN6I_TCON0_LVDS_ANA0_EN_MB,
  135. SUN6I_TCON0_LVDS_ANA0_EN_MB);
  136. udelay(2);
  137. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
  138. SUN6I_TCON0_LVDS_ANA0_EN_DRVC,
  139. SUN6I_TCON0_LVDS_ANA0_EN_DRVC);
  140. if (sun4i_tcon_get_pixel_depth(encoder) == 18)
  141. val = 7;
  142. else
  143. val = 0xf;
  144. regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG,
  145. SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf),
  146. SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
  147. }
  148. static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
  149. const struct drm_encoder *encoder,
  150. bool enabled)
  151. {
  152. if (enabled) {
  153. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
  154. SUN4I_TCON0_LVDS_IF_EN,
  155. SUN4I_TCON0_LVDS_IF_EN);
  156. if (tcon->quirks->setup_lvds_phy)
  157. tcon->quirks->setup_lvds_phy(tcon, encoder);
  158. } else {
  159. regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
  160. SUN4I_TCON0_LVDS_IF_EN, 0);
  161. }
  162. }
  163. void sun4i_tcon_set_status(struct sun4i_tcon *tcon,
  164. const struct drm_encoder *encoder,
  165. bool enabled)
  166. {
  167. bool is_lvds = false;
  168. int channel;
  169. switch (encoder->encoder_type) {
  170. case DRM_MODE_ENCODER_LVDS:
  171. is_lvds = true;
  172. fallthrough;
  173. case DRM_MODE_ENCODER_DSI:
  174. case DRM_MODE_ENCODER_NONE:
  175. channel = 0;
  176. break;
  177. case DRM_MODE_ENCODER_TMDS:
  178. case DRM_MODE_ENCODER_TVDAC:
  179. channel = 1;
  180. break;
  181. default:
  182. DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
  183. return;
  184. }
  185. if (is_lvds && !enabled)
  186. sun4i_tcon_lvds_set_status(tcon, encoder, false);
  187. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  188. SUN4I_TCON_GCTL_TCON_ENABLE,
  189. enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0);
  190. if (is_lvds && enabled)
  191. sun4i_tcon_lvds_set_status(tcon, encoder, true);
  192. sun4i_tcon_channel_set_status(tcon, channel, enabled);
  193. }
  194. void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable)
  195. {
  196. u32 mask, val = 0;
  197. DRM_DEBUG_DRIVER("%sabling VBLANK interrupt\n", enable ? "En" : "Dis");
  198. mask = SUN4I_TCON_GINT0_VBLANK_ENABLE(0) |
  199. SUN4I_TCON_GINT0_VBLANK_ENABLE(1) |
  200. SUN4I_TCON_GINT0_TCON0_TRI_FINISH_ENABLE;
  201. if (enable)
  202. val = mask;
  203. regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, mask, val);
  204. }
  205. EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
  206. /*
  207. * This function is a helper for TCON output muxing. The TCON output
  208. * muxing control register in earlier SoCs (without the TCON TOP block)
  209. * are located in TCON0. This helper returns a pointer to TCON0's
  210. * sun4i_tcon structure, or NULL if not found.
  211. */
  212. static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
  213. {
  214. struct sun4i_drv *drv = drm->dev_private;
  215. struct sun4i_tcon *tcon;
  216. list_for_each_entry(tcon, &drv->tcon_list, list)
  217. if (tcon->id == 0)
  218. return tcon;
  219. dev_warn(drm->dev,
  220. "TCON0 not found, display output muxing may not work\n");
  221. return NULL;
  222. }
  223. static void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
  224. const struct drm_encoder *encoder)
  225. {
  226. int ret = -ENOTSUPP;
  227. if (tcon->quirks->set_mux)
  228. ret = tcon->quirks->set_mux(tcon, encoder);
  229. DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
  230. encoder->name, encoder->crtc->name, ret);
  231. }
  232. static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode,
  233. int channel)
  234. {
  235. int delay = mode->vtotal - mode->vdisplay;
  236. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  237. delay /= 2;
  238. if (channel == 1)
  239. delay -= 2;
  240. delay = min(delay, 30);
  241. DRM_DEBUG_DRIVER("TCON %d clock delay %u\n", channel, delay);
  242. return delay;
  243. }
  244. static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
  245. const struct drm_display_mode *mode)
  246. {
  247. /* Configure the dot clock */
  248. clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
  249. /* Set the resolution */
  250. regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
  251. SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) |
  252. SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay));
  253. }
  254. static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon,
  255. const struct drm_connector *connector)
  256. {
  257. u32 bus_format = 0;
  258. u32 val = 0;
  259. /* XXX Would this ever happen? */
  260. if (!connector)
  261. return;
  262. /*
  263. * FIXME: Undocumented bits
  264. *
  265. * The whole dithering process and these parameters are not
  266. * explained in the vendor documents or BSP kernel code.
  267. */
  268. regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PR_REG, 0x11111111);
  269. regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PG_REG, 0x11111111);
  270. regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PB_REG, 0x11111111);
  271. regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LR_REG, 0x11111111);
  272. regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LG_REG, 0x11111111);
  273. regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LB_REG, 0x11111111);
  274. regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL0_REG, 0x01010000);
  275. regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL1_REG, 0x15151111);
  276. regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL2_REG, 0x57575555);
  277. regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL3_REG, 0x7f7f7777);
  278. /* Do dithering if panel only supports 6 bits per color */
  279. if (connector->display_info.bpc == 6)
  280. val |= SUN4I_TCON0_FRM_CTL_EN;
  281. if (connector->display_info.num_bus_formats == 1)
  282. bus_format = connector->display_info.bus_formats[0];
  283. /* Check the connection format */
  284. switch (bus_format) {
  285. case MEDIA_BUS_FMT_RGB565_1X16:
  286. /* R and B components are only 5 bits deep */
  287. val |= SUN4I_TCON0_FRM_CTL_MODE_R;
  288. val |= SUN4I_TCON0_FRM_CTL_MODE_B;
  289. fallthrough;
  290. case MEDIA_BUS_FMT_RGB666_1X18:
  291. case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
  292. /* Fall through: enable dithering */
  293. val |= SUN4I_TCON0_FRM_CTL_EN;
  294. break;
  295. }
  296. /* Write dithering settings */
  297. regmap_write(tcon->regs, SUN4I_TCON_FRM_CTL_REG, val);
  298. }
  299. static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon,
  300. const struct drm_encoder *encoder,
  301. const struct drm_display_mode *mode)
  302. {
  303. /* TODO support normal CPU interface modes */
  304. struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
  305. struct mipi_dsi_device *device = dsi->device;
  306. u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
  307. u8 lanes = device->lanes;
  308. u32 block_space, start_delay;
  309. u32 tcon_div;
  310. tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
  311. tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
  312. sun4i_tcon0_mode_set_common(tcon, mode);
  313. /* Set dithering if needed */
  314. sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
  315. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  316. SUN4I_TCON0_CTL_IF_MASK,
  317. SUN4I_TCON0_CTL_IF_8080);
  318. regmap_write(tcon->regs, SUN4I_TCON_ECC_FIFO_REG,
  319. SUN4I_TCON_ECC_FIFO_EN);
  320. regmap_write(tcon->regs, SUN4I_TCON0_CPU_IF_REG,
  321. SUN4I_TCON0_CPU_IF_MODE_DSI |
  322. SUN4I_TCON0_CPU_IF_TRI_FIFO_FLUSH |
  323. SUN4I_TCON0_CPU_IF_TRI_FIFO_EN |
  324. SUN4I_TCON0_CPU_IF_TRI_EN);
  325. /*
  326. * This looks suspicious, but it works...
  327. *
  328. * The datasheet says that this should be set higher than 20 *
  329. * pixel cycle, but it's not clear what a pixel cycle is.
  330. */
  331. regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
  332. tcon_div &= GENMASK(6, 0);
  333. block_space = mode->htotal * bpp / (tcon_div * lanes);
  334. block_space -= mode->hdisplay + 40;
  335. regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
  336. SUN4I_TCON0_CPU_TRI0_BLOCK_SPACE(block_space) |
  337. SUN4I_TCON0_CPU_TRI0_BLOCK_SIZE(mode->hdisplay));
  338. regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI1_REG,
  339. SUN4I_TCON0_CPU_TRI1_BLOCK_NUM(mode->vdisplay));
  340. start_delay = (mode->crtc_vtotal - mode->crtc_vdisplay - 10 - 1);
  341. start_delay = start_delay * mode->crtc_htotal * 149;
  342. start_delay = start_delay / (mode->crtc_clock / 1000) / 8;
  343. regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI2_REG,
  344. SUN4I_TCON0_CPU_TRI2_TRANS_START_SET(10) |
  345. SUN4I_TCON0_CPU_TRI2_START_DELAY(start_delay));
  346. /*
  347. * The Allwinner BSP has a comment that the period should be
  348. * the display clock * 15, but uses an hardcoded 3000...
  349. */
  350. regmap_write(tcon->regs, SUN4I_TCON_SAFE_PERIOD_REG,
  351. SUN4I_TCON_SAFE_PERIOD_NUM(3000) |
  352. SUN4I_TCON_SAFE_PERIOD_MODE(3));
  353. /* Enable the output on the pins */
  354. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG,
  355. 0xe0000000);
  356. }
  357. static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon,
  358. const struct drm_encoder *encoder,
  359. const struct drm_display_mode *mode)
  360. {
  361. unsigned int bp;
  362. u8 clk_delay;
  363. u32 reg, val = 0;
  364. WARN_ON(!tcon->quirks->has_channel_0);
  365. tcon->dclk_min_div = 7;
  366. tcon->dclk_max_div = 7;
  367. sun4i_tcon0_mode_set_common(tcon, mode);
  368. /* Set dithering if needed */
  369. sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
  370. /* Adjust clock delay */
  371. clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
  372. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  373. SUN4I_TCON0_CTL_CLK_DELAY_MASK,
  374. SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
  375. /*
  376. * This is called a backporch in the register documentation,
  377. * but it really is the back porch + hsync
  378. */
  379. bp = mode->crtc_htotal - mode->crtc_hsync_start;
  380. DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
  381. mode->crtc_htotal, bp);
  382. /* Set horizontal display timings */
  383. regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
  384. SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) |
  385. SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
  386. /*
  387. * This is called a backporch in the register documentation,
  388. * but it really is the back porch + hsync
  389. */
  390. bp = mode->crtc_vtotal - mode->crtc_vsync_start;
  391. DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
  392. mode->crtc_vtotal, bp);
  393. /* Set vertical display timings */
  394. regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
  395. SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
  396. SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
  397. reg = SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0;
  398. if (sun4i_tcon_get_pixel_depth(encoder) == 24)
  399. reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS;
  400. else
  401. reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS;
  402. regmap_write(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, reg);
  403. /* Setup the polarity of the various signals */
  404. if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
  405. val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
  406. if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
  407. val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
  408. regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
  409. /* Map output pins to channel 0 */
  410. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  411. SUN4I_TCON_GCTL_IOMAP_MASK,
  412. SUN4I_TCON_GCTL_IOMAP_TCON0);
  413. /* Enable the output on the pins */
  414. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000);
  415. }
  416. static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
  417. const struct drm_encoder *encoder,
  418. const struct drm_display_mode *mode)
  419. {
  420. struct drm_connector *connector = sun4i_tcon_get_connector(encoder);
  421. const struct drm_display_info *info = &connector->display_info;
  422. unsigned int bp, hsync, vsync;
  423. u8 clk_delay;
  424. u32 val = 0;
  425. WARN_ON(!tcon->quirks->has_channel_0);
  426. tcon->dclk_min_div = tcon->quirks->dclk_min_div;
  427. tcon->dclk_max_div = 127;
  428. sun4i_tcon0_mode_set_common(tcon, mode);
  429. /* Set dithering if needed */
  430. sun4i_tcon0_mode_set_dithering(tcon, connector);
  431. /* Adjust clock delay */
  432. clk_delay = sun4i_tcon_get_clk_delay(mode, 0);
  433. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  434. SUN4I_TCON0_CTL_CLK_DELAY_MASK,
  435. SUN4I_TCON0_CTL_CLK_DELAY(clk_delay));
  436. /*
  437. * This is called a backporch in the register documentation,
  438. * but it really is the back porch + hsync
  439. */
  440. bp = mode->crtc_htotal - mode->crtc_hsync_start;
  441. DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
  442. mode->crtc_htotal, bp);
  443. /* Set horizontal display timings */
  444. regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG,
  445. SUN4I_TCON0_BASIC1_H_TOTAL(mode->crtc_htotal) |
  446. SUN4I_TCON0_BASIC1_H_BACKPORCH(bp));
  447. /*
  448. * This is called a backporch in the register documentation,
  449. * but it really is the back porch + hsync
  450. */
  451. bp = mode->crtc_vtotal - mode->crtc_vsync_start;
  452. DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
  453. mode->crtc_vtotal, bp);
  454. /* Set vertical display timings */
  455. regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG,
  456. SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) |
  457. SUN4I_TCON0_BASIC2_V_BACKPORCH(bp));
  458. /* Set Hsync and Vsync length */
  459. hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
  460. vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
  461. DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync);
  462. regmap_write(tcon->regs, SUN4I_TCON0_BASIC3_REG,
  463. SUN4I_TCON0_BASIC3_V_SYNC(vsync) |
  464. SUN4I_TCON0_BASIC3_H_SYNC(hsync));
  465. /* Setup the polarity of the various signals */
  466. if (mode->flags & DRM_MODE_FLAG_PHSYNC)
  467. val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
  468. if (mode->flags & DRM_MODE_FLAG_PVSYNC)
  469. val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
  470. if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
  471. val |= SUN4I_TCON0_IO_POL_DE_NEGATIVE;
  472. if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
  473. val |= SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE;
  474. regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG,
  475. SUN4I_TCON0_IO_POL_HSYNC_POSITIVE |
  476. SUN4I_TCON0_IO_POL_VSYNC_POSITIVE |
  477. SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE |
  478. SUN4I_TCON0_IO_POL_DE_NEGATIVE,
  479. val);
  480. /* Map output pins to channel 0 */
  481. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  482. SUN4I_TCON_GCTL_IOMAP_MASK,
  483. SUN4I_TCON_GCTL_IOMAP_TCON0);
  484. /* Enable the output on the pins */
  485. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0);
  486. }
  487. static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
  488. const struct drm_display_mode *mode)
  489. {
  490. unsigned int bp, hsync, vsync, vtotal;
  491. u8 clk_delay;
  492. u32 val;
  493. WARN_ON(!tcon->quirks->has_channel_1);
  494. /* Configure the dot clock */
  495. clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
  496. /* Adjust clock delay */
  497. clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
  498. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  499. SUN4I_TCON1_CTL_CLK_DELAY_MASK,
  500. SUN4I_TCON1_CTL_CLK_DELAY(clk_delay));
  501. /* Set interlaced mode */
  502. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  503. val = SUN4I_TCON1_CTL_INTERLACE_ENABLE;
  504. else
  505. val = 0;
  506. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  507. SUN4I_TCON1_CTL_INTERLACE_ENABLE,
  508. val);
  509. /* Set the input resolution */
  510. regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG,
  511. SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) |
  512. SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay));
  513. /* Set the upscaling resolution */
  514. regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG,
  515. SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) |
  516. SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay));
  517. /* Set the output resolution */
  518. regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG,
  519. SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) |
  520. SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay));
  521. /* Set horizontal display timings */
  522. bp = mode->crtc_htotal - mode->crtc_hsync_start;
  523. DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n",
  524. mode->htotal, bp);
  525. regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG,
  526. SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) |
  527. SUN4I_TCON1_BASIC3_H_BACKPORCH(bp));
  528. bp = mode->crtc_vtotal - mode->crtc_vsync_start;
  529. DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n",
  530. mode->crtc_vtotal, bp);
  531. /*
  532. * The vertical resolution needs to be doubled in all
  533. * cases. We could use crtc_vtotal and always multiply by two,
  534. * but that leads to a rounding error in interlace when vtotal
  535. * is odd.
  536. *
  537. * This happens with TV's PAL for example, where vtotal will
  538. * be 625, crtc_vtotal 312, and thus crtc_vtotal * 2 will be
  539. * 624, which apparently confuses the hardware.
  540. *
  541. * To work around this, we will always use vtotal, and
  542. * multiply by two only if we're not in interlace.
  543. */
  544. vtotal = mode->vtotal;
  545. if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
  546. vtotal = vtotal * 2;
  547. /* Set vertical display timings */
  548. regmap_write(tcon->regs, SUN4I_TCON1_BASIC4_REG,
  549. SUN4I_TCON1_BASIC4_V_TOTAL(vtotal) |
  550. SUN4I_TCON1_BASIC4_V_BACKPORCH(bp));
  551. /* Set Hsync and Vsync length */
  552. hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
  553. vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
  554. DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync);
  555. regmap_write(tcon->regs, SUN4I_TCON1_BASIC5_REG,
  556. SUN4I_TCON1_BASIC5_V_SYNC(vsync) |
  557. SUN4I_TCON1_BASIC5_H_SYNC(hsync));
  558. /* Setup the polarity of multiple signals */
  559. if (tcon->quirks->polarity_in_ch0) {
  560. val = 0;
  561. if (mode->flags & DRM_MODE_FLAG_PHSYNC)
  562. val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE;
  563. if (mode->flags & DRM_MODE_FLAG_PVSYNC)
  564. val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE;
  565. regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val);
  566. } else {
  567. /* according to vendor driver, this bit must be always set */
  568. val = SUN4I_TCON1_IO_POL_UNKNOWN;
  569. if (mode->flags & DRM_MODE_FLAG_PHSYNC)
  570. val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE;
  571. if (mode->flags & DRM_MODE_FLAG_PVSYNC)
  572. val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE;
  573. regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val);
  574. }
  575. /* Map output pins to channel 1 */
  576. regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG,
  577. SUN4I_TCON_GCTL_IOMAP_MASK,
  578. SUN4I_TCON_GCTL_IOMAP_TCON1);
  579. }
  580. void sun4i_tcon_mode_set(struct sun4i_tcon *tcon,
  581. const struct drm_encoder *encoder,
  582. const struct drm_display_mode *mode)
  583. {
  584. switch (encoder->encoder_type) {
  585. case DRM_MODE_ENCODER_DSI:
  586. /* DSI is tied to special case of CPU interface */
  587. sun4i_tcon0_mode_set_cpu(tcon, encoder, mode);
  588. break;
  589. case DRM_MODE_ENCODER_LVDS:
  590. sun4i_tcon0_mode_set_lvds(tcon, encoder, mode);
  591. break;
  592. case DRM_MODE_ENCODER_NONE:
  593. sun4i_tcon0_mode_set_rgb(tcon, encoder, mode);
  594. sun4i_tcon_set_mux(tcon, 0, encoder);
  595. break;
  596. case DRM_MODE_ENCODER_TVDAC:
  597. case DRM_MODE_ENCODER_TMDS:
  598. sun4i_tcon1_mode_set(tcon, mode);
  599. sun4i_tcon_set_mux(tcon, 1, encoder);
  600. break;
  601. default:
  602. DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n");
  603. }
  604. }
  605. EXPORT_SYMBOL(sun4i_tcon_mode_set);
  606. static void sun4i_tcon_finish_page_flip(struct drm_device *dev,
  607. struct sun4i_crtc *scrtc)
  608. {
  609. unsigned long flags;
  610. spin_lock_irqsave(&dev->event_lock, flags);
  611. if (scrtc->event) {
  612. drm_crtc_send_vblank_event(&scrtc->crtc, scrtc->event);
  613. drm_crtc_vblank_put(&scrtc->crtc);
  614. scrtc->event = NULL;
  615. }
  616. spin_unlock_irqrestore(&dev->event_lock, flags);
  617. }
  618. static irqreturn_t sun4i_tcon_handler(int irq, void *private)
  619. {
  620. struct sun4i_tcon *tcon = private;
  621. struct drm_device *drm = tcon->drm;
  622. struct sun4i_crtc *scrtc = tcon->crtc;
  623. struct sunxi_engine *engine = scrtc->engine;
  624. unsigned int status;
  625. regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status);
  626. if (!(status & (SUN4I_TCON_GINT0_VBLANK_INT(0) |
  627. SUN4I_TCON_GINT0_VBLANK_INT(1) |
  628. SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT)))
  629. return IRQ_NONE;
  630. drm_crtc_handle_vblank(&scrtc->crtc);
  631. sun4i_tcon_finish_page_flip(drm, scrtc);
  632. /* Acknowledge the interrupt */
  633. regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG,
  634. SUN4I_TCON_GINT0_VBLANK_INT(0) |
  635. SUN4I_TCON_GINT0_VBLANK_INT(1) |
  636. SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT,
  637. 0);
  638. if (engine->ops->vblank_quirk)
  639. engine->ops->vblank_quirk(engine);
  640. return IRQ_HANDLED;
  641. }
  642. static int sun4i_tcon_init_clocks(struct device *dev,
  643. struct sun4i_tcon *tcon)
  644. {
  645. tcon->clk = devm_clk_get_enabled(dev, "ahb");
  646. if (IS_ERR(tcon->clk)) {
  647. dev_err(dev, "Couldn't get the TCON bus clock\n");
  648. return PTR_ERR(tcon->clk);
  649. }
  650. if (tcon->quirks->has_channel_0) {
  651. tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0");
  652. if (IS_ERR(tcon->sclk0)) {
  653. dev_err(dev, "Couldn't get the TCON channel 0 clock\n");
  654. return PTR_ERR(tcon->sclk0);
  655. }
  656. }
  657. if (tcon->quirks->has_channel_1) {
  658. tcon->sclk1 = devm_clk_get(dev, "tcon-ch1");
  659. if (IS_ERR(tcon->sclk1)) {
  660. dev_err(dev, "Couldn't get the TCON channel 1 clock\n");
  661. return PTR_ERR(tcon->sclk1);
  662. }
  663. }
  664. return 0;
  665. }
  666. static int sun4i_tcon_init_irq(struct device *dev,
  667. struct sun4i_tcon *tcon)
  668. {
  669. struct platform_device *pdev = to_platform_device(dev);
  670. int irq, ret;
  671. irq = platform_get_irq(pdev, 0);
  672. if (irq < 0)
  673. return irq;
  674. ret = devm_request_irq(dev, irq, sun4i_tcon_handler, 0,
  675. dev_name(dev), tcon);
  676. if (ret) {
  677. dev_err(dev, "Couldn't request the IRQ\n");
  678. return ret;
  679. }
  680. return 0;
  681. }
  682. static const struct regmap_config sun4i_tcon_regmap_config = {
  683. .reg_bits = 32,
  684. .val_bits = 32,
  685. .reg_stride = 4,
  686. .max_register = 0x800,
  687. };
  688. static int sun4i_tcon_init_regmap(struct device *dev,
  689. struct sun4i_tcon *tcon)
  690. {
  691. struct platform_device *pdev = to_platform_device(dev);
  692. void __iomem *regs;
  693. regs = devm_platform_ioremap_resource(pdev, 0);
  694. if (IS_ERR(regs))
  695. return PTR_ERR(regs);
  696. tcon->regs = devm_regmap_init_mmio(dev, regs,
  697. &sun4i_tcon_regmap_config);
  698. if (IS_ERR(tcon->regs)) {
  699. dev_err(dev, "Couldn't create the TCON regmap\n");
  700. return PTR_ERR(tcon->regs);
  701. }
  702. /* Make sure the TCON is disabled and all IRQs are off */
  703. regmap_write(tcon->regs, SUN4I_TCON_GCTL_REG, 0);
  704. regmap_write(tcon->regs, SUN4I_TCON_GINT0_REG, 0);
  705. regmap_write(tcon->regs, SUN4I_TCON_GINT1_REG, 0);
  706. /* Disable IO lines and set them to tristate */
  707. regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, ~0);
  708. regmap_write(tcon->regs, SUN4I_TCON1_IO_TRI_REG, ~0);
  709. return 0;
  710. }
  711. /*
  712. * On SoCs with the old display pipeline design (Display Engine 1.0),
  713. * the TCON is always tied to just one backend. Hence we can traverse
  714. * the of_graph upwards to find the backend our tcon is connected to,
  715. * and take its ID as our own.
  716. *
  717. * We can either identify backends from their compatible strings, which
  718. * means maintaining a large list of them. Or, since the backend is
  719. * registered and binded before the TCON, we can just go through the
  720. * list of registered backends and compare the device node.
  721. *
  722. * As the structures now store engines instead of backends, here this
  723. * function in fact searches the corresponding engine, and the ID is
  724. * requested via the get_id function of the engine.
  725. */
  726. static struct sunxi_engine *
  727. sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv,
  728. struct device_node *node,
  729. u32 port_id)
  730. {
  731. struct device_node *port, *ep, *remote;
  732. struct sunxi_engine *engine = ERR_PTR(-EINVAL);
  733. u32 reg = 0;
  734. port = of_graph_get_port_by_id(node, port_id);
  735. if (!port)
  736. return ERR_PTR(-EINVAL);
  737. /*
  738. * This only works if there is only one path from the TCON
  739. * to any display engine. Otherwise the probe order of the
  740. * TCONs and display engines is not guaranteed. They may
  741. * either bind to the wrong one, or worse, bind to the same
  742. * one if additional checks are not done.
  743. *
  744. * Bail out if there are multiple input connections.
  745. */
  746. if (of_get_available_child_count(port) != 1)
  747. goto out_put_port;
  748. /* Get the first connection without specifying an ID */
  749. ep = of_get_next_available_child(port, NULL);
  750. if (!ep)
  751. goto out_put_port;
  752. remote = of_graph_get_remote_port_parent(ep);
  753. if (!remote)
  754. goto out_put_ep;
  755. /* does this node match any registered engines? */
  756. list_for_each_entry(engine, &drv->engine_list, list)
  757. if (remote == engine->node)
  758. goto out_put_remote;
  759. /*
  760. * According to device tree binding input ports have even id
  761. * number and output ports have odd id. Since component with
  762. * more than one input and one output (TCON TOP) exits, correct
  763. * remote input id has to be calculated by subtracting 1 from
  764. * remote output id. If this for some reason can't be done, 0
  765. * is used as input port id.
  766. */
  767. of_node_put(port);
  768. port = of_graph_get_remote_port(ep);
  769. if (!of_property_read_u32(port, "reg", &reg) && reg > 0)
  770. reg -= 1;
  771. /* keep looking through upstream ports */
  772. engine = sun4i_tcon_find_engine_traverse(drv, remote, reg);
  773. out_put_remote:
  774. of_node_put(remote);
  775. out_put_ep:
  776. of_node_put(ep);
  777. out_put_port:
  778. of_node_put(port);
  779. return engine;
  780. }
  781. /*
  782. * The device tree binding says that the remote endpoint ID of any
  783. * connection between components, up to and including the TCON, of
  784. * the display pipeline should be equal to the actual ID of the local
  785. * component. Thus we can look at any one of the input connections of
  786. * the TCONs, and use that connection's remote endpoint ID as our own.
  787. *
  788. * Since the user of this function already finds the input port,
  789. * the port is passed in directly without further checks.
  790. */
  791. static int sun4i_tcon_of_get_id_from_port(struct device_node *port)
  792. {
  793. struct device_node *ep;
  794. int ret = -EINVAL;
  795. /* try finding an upstream endpoint */
  796. for_each_available_child_of_node(port, ep) {
  797. struct device_node *remote;
  798. u32 reg;
  799. remote = of_graph_get_remote_endpoint(ep);
  800. if (!remote)
  801. continue;
  802. ret = of_property_read_u32(remote, "reg", &reg);
  803. if (ret)
  804. continue;
  805. ret = reg;
  806. }
  807. return ret;
  808. }
  809. /*
  810. * Once we know the TCON's id, we can look through the list of
  811. * engines to find a matching one. We assume all engines have
  812. * been probed and added to the list.
  813. */
  814. static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv,
  815. int id)
  816. {
  817. struct sunxi_engine *engine;
  818. list_for_each_entry(engine, &drv->engine_list, list)
  819. if (engine->id == id)
  820. return engine;
  821. return ERR_PTR(-EINVAL);
  822. }
  823. static bool sun4i_tcon_connected_to_tcon_top(struct device_node *node)
  824. {
  825. struct device_node *remote;
  826. bool ret = false;
  827. remote = of_graph_get_remote_node(node, 0, -1);
  828. if (remote) {
  829. ret = !!(IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
  830. of_match_node(sun8i_tcon_top_of_table, remote));
  831. of_node_put(remote);
  832. }
  833. return ret;
  834. }
  835. static int sun4i_tcon_get_index(struct sun4i_drv *drv)
  836. {
  837. struct list_head *pos;
  838. int size = 0;
  839. /*
  840. * Because TCON is added to the list at the end of the probe
  841. * (after this function is called), index of the current TCON
  842. * will be same as current TCON list size.
  843. */
  844. list_for_each(pos, &drv->tcon_list)
  845. ++size;
  846. return size;
  847. }
  848. /*
  849. * On SoCs with the old display pipeline design (Display Engine 1.0),
  850. * we assumed the TCON was always tied to just one backend. However
  851. * this proved not to be the case. On the A31, the TCON can select
  852. * either backend as its source. On the A20 (and likely on the A10),
  853. * the backend can choose which TCON to output to.
  854. *
  855. * The device tree binding says that the remote endpoint ID of any
  856. * connection between components, up to and including the TCON, of
  857. * the display pipeline should be equal to the actual ID of the local
  858. * component. Thus we should be able to look at any one of the input
  859. * connections of the TCONs, and use that connection's remote endpoint
  860. * ID as our own.
  861. *
  862. * However the connections between the backend and TCON were assumed
  863. * to be always singular, and their endpoit IDs were all incorrectly
  864. * set to 0. This means for these old device trees, we cannot just look
  865. * up the remote endpoint ID of a TCON input endpoint. TCON1 would be
  866. * incorrectly identified as TCON0.
  867. *
  868. * This function first checks if the TCON node has 2 input endpoints.
  869. * If so, then the device tree is a corrected version, and it will use
  870. * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above
  871. * to fetch the ID and engine directly. If not, then it is likely an
  872. * old device trees, where the endpoint IDs were incorrect, but did not
  873. * have endpoint connections between the backend and TCON across
  874. * different display pipelines. It will fall back to the old method of
  875. * traversing the of_graph to try and find a matching engine by device
  876. * node.
  877. *
  878. * In the case of single display pipeline device trees, either method
  879. * works.
  880. */
  881. static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
  882. struct device_node *node)
  883. {
  884. struct device_node *port;
  885. struct sunxi_engine *engine;
  886. port = of_graph_get_port_by_id(node, 0);
  887. if (!port)
  888. return ERR_PTR(-EINVAL);
  889. /*
  890. * Is this a corrected device tree with cross pipeline
  891. * connections between the backend and TCON?
  892. */
  893. if (of_get_child_count(port) > 1) {
  894. int id;
  895. /*
  896. * When pipeline has the same number of TCONs and engines which
  897. * are represented by frontends/backends (DE1) or mixers (DE2),
  898. * we match them by their respective IDs. However, if pipeline
  899. * contains TCON TOP, chances are that there are either more
  900. * TCONs than engines (R40) or TCONs with non-consecutive ids.
  901. * (H6). In that case it's easier just use TCON index in list
  902. * as an id. That means that on R40, any 2 TCONs can be enabled
  903. * in DT out of 4 (there are 2 mixers). Due to the design of
  904. * TCON TOP, remaining 2 TCONs can't be connected to anything
  905. * anyway.
  906. */
  907. if (sun4i_tcon_connected_to_tcon_top(node))
  908. id = sun4i_tcon_get_index(drv);
  909. else
  910. id = sun4i_tcon_of_get_id_from_port(port);
  911. /* Get our engine by matching our ID */
  912. engine = sun4i_tcon_get_engine_by_id(drv, id);
  913. of_node_put(port);
  914. return engine;
  915. }
  916. /* Fallback to old method by traversing input endpoints */
  917. of_node_put(port);
  918. return sun4i_tcon_find_engine_traverse(drv, node, 0);
  919. }
  920. static int sun4i_tcon_bind(struct device *dev, struct device *master,
  921. void *data)
  922. {
  923. struct drm_device *drm = data;
  924. struct sun4i_drv *drv = drm->dev_private;
  925. struct sunxi_engine *engine;
  926. struct device_node *remote;
  927. struct sun4i_tcon *tcon;
  928. struct reset_control *edp_rstc;
  929. bool has_lvds_rst, has_lvds_alt, can_lvds;
  930. int ret;
  931. engine = sun4i_tcon_find_engine(drv, dev->of_node);
  932. if (IS_ERR(engine)) {
  933. dev_err(dev, "Couldn't find matching engine\n");
  934. return -EPROBE_DEFER;
  935. }
  936. tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
  937. if (!tcon)
  938. return -ENOMEM;
  939. dev_set_drvdata(dev, tcon);
  940. tcon->drm = drm;
  941. tcon->dev = dev;
  942. tcon->id = engine->id;
  943. tcon->quirks = of_device_get_match_data(dev);
  944. tcon->lcd_rst = devm_reset_control_get(dev, "lcd");
  945. if (IS_ERR(tcon->lcd_rst)) {
  946. dev_err(dev, "Couldn't get our reset line\n");
  947. return PTR_ERR(tcon->lcd_rst);
  948. }
  949. if (tcon->quirks->needs_edp_reset) {
  950. edp_rstc = devm_reset_control_get_shared(dev, "edp");
  951. if (IS_ERR(edp_rstc)) {
  952. dev_err(dev, "Couldn't get edp reset line\n");
  953. return PTR_ERR(edp_rstc);
  954. }
  955. ret = reset_control_deassert(edp_rstc);
  956. if (ret) {
  957. dev_err(dev, "Couldn't deassert edp reset line\n");
  958. return ret;
  959. }
  960. }
  961. /* Make sure our TCON is reset */
  962. ret = reset_control_reset(tcon->lcd_rst);
  963. if (ret) {
  964. dev_err(dev, "Couldn't deassert our reset line\n");
  965. return ret;
  966. }
  967. if (tcon->quirks->supports_lvds) {
  968. /*
  969. * This can only be made optional since we've had DT
  970. * nodes without the LVDS reset properties.
  971. *
  972. * If the property is missing, just disable LVDS, and
  973. * print a warning.
  974. */
  975. tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds");
  976. if (IS_ERR(tcon->lvds_rst)) {
  977. dev_err(dev, "Couldn't get our reset line\n");
  978. return PTR_ERR(tcon->lvds_rst);
  979. } else if (tcon->lvds_rst) {
  980. has_lvds_rst = true;
  981. reset_control_reset(tcon->lvds_rst);
  982. } else {
  983. has_lvds_rst = false;
  984. }
  985. /*
  986. * This can only be made optional since we've had DT
  987. * nodes without the LVDS reset properties.
  988. *
  989. * If the property is missing, just disable LVDS, and
  990. * print a warning.
  991. */
  992. if (tcon->quirks->has_lvds_alt) {
  993. tcon->lvds_pll = devm_clk_get(dev, "lvds-alt");
  994. if (IS_ERR(tcon->lvds_pll)) {
  995. if (PTR_ERR(tcon->lvds_pll) == -ENOENT) {
  996. has_lvds_alt = false;
  997. } else {
  998. dev_err(dev, "Couldn't get the LVDS PLL\n");
  999. return PTR_ERR(tcon->lvds_pll);
  1000. }
  1001. } else {
  1002. has_lvds_alt = true;
  1003. }
  1004. }
  1005. if (!has_lvds_rst ||
  1006. (tcon->quirks->has_lvds_alt && !has_lvds_alt)) {
  1007. dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n");
  1008. dev_warn(dev, "LVDS output disabled\n");
  1009. can_lvds = false;
  1010. } else {
  1011. can_lvds = true;
  1012. }
  1013. } else {
  1014. can_lvds = false;
  1015. }
  1016. ret = sun4i_tcon_init_clocks(dev, tcon);
  1017. if (ret) {
  1018. dev_err(dev, "Couldn't init our TCON clocks\n");
  1019. goto err_assert_reset;
  1020. }
  1021. ret = sun4i_tcon_init_regmap(dev, tcon);
  1022. if (ret) {
  1023. dev_err(dev, "Couldn't init our TCON regmap\n");
  1024. goto err_assert_reset;
  1025. }
  1026. if (tcon->quirks->has_channel_0) {
  1027. ret = sun4i_dclk_create(dev, tcon);
  1028. if (ret) {
  1029. dev_err(dev, "Couldn't create our TCON dot clock\n");
  1030. goto err_assert_reset;
  1031. }
  1032. }
  1033. ret = sun4i_tcon_init_irq(dev, tcon);
  1034. if (ret) {
  1035. dev_err(dev, "Couldn't init our TCON interrupts\n");
  1036. goto err_free_dotclock;
  1037. }
  1038. tcon->crtc = sun4i_crtc_init(drm, engine, tcon);
  1039. if (IS_ERR(tcon->crtc)) {
  1040. dev_err(dev, "Couldn't create our CRTC\n");
  1041. ret = PTR_ERR(tcon->crtc);
  1042. goto err_free_dotclock;
  1043. }
  1044. if (tcon->quirks->has_channel_0) {
  1045. /*
  1046. * If we have an LVDS panel connected to the TCON, we should
  1047. * just probe the LVDS connector. Otherwise, just probe RGB as
  1048. * we used to.
  1049. */
  1050. remote = of_graph_get_remote_node(dev->of_node, 1, 0);
  1051. if (of_device_is_compatible(remote, "panel-lvds"))
  1052. if (can_lvds)
  1053. ret = sun4i_lvds_init(drm, tcon);
  1054. else
  1055. ret = -EINVAL;
  1056. else
  1057. ret = sun4i_rgb_init(drm, tcon);
  1058. of_node_put(remote);
  1059. if (ret < 0)
  1060. goto err_free_dotclock;
  1061. }
  1062. if (tcon->quirks->needs_de_be_mux) {
  1063. /*
  1064. * We assume there is no dynamic muxing of backends
  1065. * and TCONs, so we select the backend with same ID.
  1066. *
  1067. * While dynamic selection might be interesting, since
  1068. * the CRTC is tied to the TCON, while the layers are
  1069. * tied to the backends, this means, we will need to
  1070. * switch between groups of layers. There might not be
  1071. * a way to represent this constraint in DRM.
  1072. */
  1073. regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG,
  1074. SUN4I_TCON0_CTL_SRC_SEL_MASK,
  1075. tcon->id);
  1076. regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG,
  1077. SUN4I_TCON1_CTL_SRC_SEL_MASK,
  1078. tcon->id);
  1079. }
  1080. list_add_tail(&tcon->list, &drv->tcon_list);
  1081. return 0;
  1082. err_free_dotclock:
  1083. if (tcon->quirks->has_channel_0)
  1084. sun4i_dclk_free(tcon);
  1085. err_assert_reset:
  1086. reset_control_assert(tcon->lcd_rst);
  1087. return ret;
  1088. }
  1089. static void sun4i_tcon_unbind(struct device *dev, struct device *master,
  1090. void *data)
  1091. {
  1092. struct sun4i_tcon *tcon = dev_get_drvdata(dev);
  1093. list_del(&tcon->list);
  1094. if (tcon->quirks->has_channel_0)
  1095. sun4i_dclk_free(tcon);
  1096. }
  1097. static const struct component_ops sun4i_tcon_ops = {
  1098. .bind = sun4i_tcon_bind,
  1099. .unbind = sun4i_tcon_unbind,
  1100. };
  1101. static int sun4i_tcon_probe(struct platform_device *pdev)
  1102. {
  1103. struct device_node *node = pdev->dev.of_node;
  1104. const struct sun4i_tcon_quirks *quirks;
  1105. struct drm_bridge *bridge;
  1106. struct drm_panel *panel;
  1107. int ret;
  1108. quirks = of_device_get_match_data(&pdev->dev);
  1109. /* panels and bridges are present only on TCONs with channel 0 */
  1110. if (quirks->has_channel_0) {
  1111. ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge);
  1112. if (ret == -EPROBE_DEFER)
  1113. return ret;
  1114. }
  1115. return component_add(&pdev->dev, &sun4i_tcon_ops);
  1116. }
  1117. static int sun4i_tcon_remove(struct platform_device *pdev)
  1118. {
  1119. component_del(&pdev->dev, &sun4i_tcon_ops);
  1120. return 0;
  1121. }
  1122. /* platform specific TCON muxing callbacks */
  1123. static int sun4i_a10_tcon_set_mux(struct sun4i_tcon *tcon,
  1124. const struct drm_encoder *encoder)
  1125. {
  1126. struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
  1127. u32 shift;
  1128. if (!tcon0)
  1129. return -EINVAL;
  1130. switch (encoder->encoder_type) {
  1131. case DRM_MODE_ENCODER_TMDS:
  1132. /* HDMI */
  1133. shift = 8;
  1134. break;
  1135. default:
  1136. return -EINVAL;
  1137. }
  1138. regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
  1139. 0x3 << shift, tcon->id << shift);
  1140. return 0;
  1141. }
  1142. static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
  1143. const struct drm_encoder *encoder)
  1144. {
  1145. u32 val;
  1146. if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
  1147. val = 1;
  1148. else
  1149. val = 0;
  1150. /*
  1151. * FIXME: Undocumented bits
  1152. */
  1153. return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
  1154. }
  1155. static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon,
  1156. const struct drm_encoder *encoder)
  1157. {
  1158. struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
  1159. u32 shift;
  1160. if (!tcon0)
  1161. return -EINVAL;
  1162. switch (encoder->encoder_type) {
  1163. case DRM_MODE_ENCODER_TMDS:
  1164. /* HDMI */
  1165. shift = 8;
  1166. break;
  1167. default:
  1168. /* TODO A31 has MIPI DSI but A31s does not */
  1169. return -EINVAL;
  1170. }
  1171. regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
  1172. 0x3 << shift, tcon->id << shift);
  1173. return 0;
  1174. }
  1175. static int sun8i_r40_tcon_tv_set_mux(struct sun4i_tcon *tcon,
  1176. const struct drm_encoder *encoder)
  1177. {
  1178. struct device_node *port, *remote;
  1179. struct platform_device *pdev;
  1180. int id, ret;
  1181. /* find TCON TOP platform device and TCON id */
  1182. port = of_graph_get_port_by_id(tcon->dev->of_node, 0);
  1183. if (!port)
  1184. return -EINVAL;
  1185. id = sun4i_tcon_of_get_id_from_port(port);
  1186. of_node_put(port);
  1187. remote = of_graph_get_remote_node(tcon->dev->of_node, 0, -1);
  1188. if (!remote)
  1189. return -EINVAL;
  1190. pdev = of_find_device_by_node(remote);
  1191. of_node_put(remote);
  1192. if (!pdev)
  1193. return -EINVAL;
  1194. if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
  1195. encoder->encoder_type == DRM_MODE_ENCODER_TMDS) {
  1196. ret = sun8i_tcon_top_set_hdmi_src(&pdev->dev, id);
  1197. if (ret) {
  1198. put_device(&pdev->dev);
  1199. return ret;
  1200. }
  1201. }
  1202. if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP)) {
  1203. ret = sun8i_tcon_top_de_config(&pdev->dev, tcon->id, id);
  1204. if (ret) {
  1205. put_device(&pdev->dev);
  1206. return ret;
  1207. }
  1208. }
  1209. return 0;
  1210. }
  1211. static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
  1212. .has_channel_0 = true,
  1213. .has_channel_1 = true,
  1214. .dclk_min_div = 4,
  1215. .set_mux = sun4i_a10_tcon_set_mux,
  1216. };
  1217. static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
  1218. .has_channel_0 = true,
  1219. .has_channel_1 = true,
  1220. .dclk_min_div = 4,
  1221. .set_mux = sun5i_a13_tcon_set_mux,
  1222. };
  1223. static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
  1224. .has_channel_0 = true,
  1225. .has_channel_1 = true,
  1226. .has_lvds_alt = true,
  1227. .needs_de_be_mux = true,
  1228. .dclk_min_div = 1,
  1229. .set_mux = sun6i_tcon_set_mux,
  1230. };
  1231. static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
  1232. .has_channel_0 = true,
  1233. .has_channel_1 = true,
  1234. .needs_de_be_mux = true,
  1235. .dclk_min_div = 1,
  1236. };
  1237. static const struct sun4i_tcon_quirks sun7i_a20_tcon0_quirks = {
  1238. .supports_lvds = true,
  1239. .has_channel_0 = true,
  1240. .has_channel_1 = true,
  1241. .dclk_min_div = 4,
  1242. /* Same display pipeline structure as A10 */
  1243. .set_mux = sun4i_a10_tcon_set_mux,
  1244. .setup_lvds_phy = sun4i_tcon_setup_lvds_phy,
  1245. };
  1246. static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
  1247. .has_channel_0 = true,
  1248. .has_channel_1 = true,
  1249. .dclk_min_div = 4,
  1250. /* Same display pipeline structure as A10 */
  1251. .set_mux = sun4i_a10_tcon_set_mux,
  1252. };
  1253. static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
  1254. .has_channel_0 = true,
  1255. .has_lvds_alt = true,
  1256. .dclk_min_div = 1,
  1257. .setup_lvds_phy = sun6i_tcon_setup_lvds_phy,
  1258. .supports_lvds = true,
  1259. };
  1260. static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
  1261. .supports_lvds = true,
  1262. .has_channel_0 = true,
  1263. .dclk_min_div = 1,
  1264. .setup_lvds_phy = sun6i_tcon_setup_lvds_phy,
  1265. };
  1266. static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = {
  1267. .has_channel_1 = true,
  1268. };
  1269. static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = {
  1270. .has_channel_1 = true,
  1271. .polarity_in_ch0 = true,
  1272. .set_mux = sun8i_r40_tcon_tv_set_mux,
  1273. };
  1274. static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
  1275. .has_channel_0 = true,
  1276. .dclk_min_div = 1,
  1277. };
  1278. static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = {
  1279. .has_channel_0 = true,
  1280. .needs_edp_reset = true,
  1281. .dclk_min_div = 1,
  1282. };
  1283. static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
  1284. .has_channel_1 = true,
  1285. .needs_edp_reset = true,
  1286. };
  1287. static const struct sun4i_tcon_quirks sun20i_d1_lcd_quirks = {
  1288. .has_channel_0 = true,
  1289. .dclk_min_div = 1,
  1290. .set_mux = sun8i_r40_tcon_tv_set_mux,
  1291. };
  1292. /* sun4i_drv uses this list to check if a device node is a TCON */
  1293. const struct of_device_id sun4i_tcon_of_table[] = {
  1294. { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks },
  1295. { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks },
  1296. { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks },
  1297. { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks },
  1298. { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks },
  1299. { .compatible = "allwinner,sun7i-a20-tcon0", .data = &sun7i_a20_tcon0_quirks },
  1300. { .compatible = "allwinner,sun7i-a20-tcon1", .data = &sun7i_a20_quirks },
  1301. { .compatible = "allwinner,sun8i-a23-tcon", .data = &sun8i_a33_quirks },
  1302. { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks },
  1303. { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks },
  1304. { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks },
  1305. { .compatible = "allwinner,sun8i-r40-tcon-tv", .data = &sun8i_r40_tv_quirks },
  1306. { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks },
  1307. { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks },
  1308. { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks },
  1309. { .compatible = "allwinner,sun20i-d1-tcon-lcd", .data = &sun20i_d1_lcd_quirks },
  1310. { .compatible = "allwinner,sun20i-d1-tcon-tv", .data = &sun8i_r40_tv_quirks },
  1311. { }
  1312. };
  1313. MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table);
  1314. EXPORT_SYMBOL(sun4i_tcon_of_table);
  1315. static struct platform_driver sun4i_tcon_platform_driver = {
  1316. .probe = sun4i_tcon_probe,
  1317. .remove = sun4i_tcon_remove,
  1318. .driver = {
  1319. .name = "sun4i-tcon",
  1320. .of_match_table = sun4i_tcon_of_table,
  1321. },
  1322. };
  1323. module_platform_driver(sun4i_tcon_platform_driver);
  1324. MODULE_AUTHOR("Maxime Ripard <[email protected]>");
  1325. MODULE_DESCRIPTION("Allwinner A10 Timing Controller Driver");
  1326. MODULE_LICENSE("GPL");