imx-hdmi.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766
  1. /*
  2. * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
  10. * for SLISHDMI13T and SLIPHDMIT IP cores
  11. *
  12. * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  13. */
  14. #include <linux/component.h>
  15. #include <linux/irq.h>
  16. #include <linux/delay.h>
  17. #include <linux/err.h>
  18. #include <linux/clk.h>
  19. #include <linux/hdmi.h>
  20. #include <linux/regmap.h>
  21. #include <linux/mfd/syscon.h>
  22. #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
  23. #include <linux/of_device.h>
  24. #include <drm/drmP.h>
  25. #include <drm/drm_crtc_helper.h>
  26. #include <drm/drm_edid.h>
  27. #include <drm/drm_encoder_slave.h>
  28. #include <video/imx-ipu-v3.h>
  29. #include "imx-hdmi.h"
  30. #include "imx-drm.h"
  31. #define HDMI_EDID_LEN 512
  32. #define RGB 0
  33. #define YCBCR444 1
  34. #define YCBCR422_16BITS 2
  35. #define YCBCR422_8BITS 3
  36. #define XVYCC444 4
  37. enum hdmi_datamap {
  38. RGB444_8B = 0x01,
  39. RGB444_10B = 0x03,
  40. RGB444_12B = 0x05,
  41. RGB444_16B = 0x07,
  42. YCbCr444_8B = 0x09,
  43. YCbCr444_10B = 0x0B,
  44. YCbCr444_12B = 0x0D,
  45. YCbCr444_16B = 0x0F,
  46. YCbCr422_8B = 0x16,
  47. YCbCr422_10B = 0x14,
  48. YCbCr422_12B = 0x12,
  49. };
  50. enum imx_hdmi_devtype {
  51. IMX6Q_HDMI,
  52. IMX6DL_HDMI,
  53. };
  54. static const u16 csc_coeff_default[3][4] = {
  55. { 0x2000, 0x0000, 0x0000, 0x0000 },
  56. { 0x0000, 0x2000, 0x0000, 0x0000 },
  57. { 0x0000, 0x0000, 0x2000, 0x0000 }
  58. };
  59. static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
  60. { 0x2000, 0x6926, 0x74fd, 0x010e },
  61. { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
  62. { 0x2000, 0x0000, 0x38b4, 0x7e3b }
  63. };
  64. static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
  65. { 0x2000, 0x7106, 0x7a02, 0x00a7 },
  66. { 0x2000, 0x3264, 0x0000, 0x7e6d },
  67. { 0x2000, 0x0000, 0x3b61, 0x7e25 }
  68. };
  69. static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
  70. { 0x2591, 0x1322, 0x074b, 0x0000 },
  71. { 0x6535, 0x2000, 0x7acc, 0x0200 },
  72. { 0x6acd, 0x7534, 0x2000, 0x0200 }
  73. };
  74. static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
  75. { 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
  76. { 0x62f0, 0x2000, 0x7d11, 0x0200 },
  77. { 0x6756, 0x78ab, 0x2000, 0x0200 }
  78. };
  79. struct hdmi_vmode {
  80. bool mdvi;
  81. bool mhsyncpolarity;
  82. bool mvsyncpolarity;
  83. bool minterlaced;
  84. bool mdataenablepolarity;
  85. unsigned int mpixelclock;
  86. unsigned int mpixelrepetitioninput;
  87. unsigned int mpixelrepetitionoutput;
  88. };
  89. struct hdmi_data_info {
  90. unsigned int enc_in_format;
  91. unsigned int enc_out_format;
  92. unsigned int enc_color_depth;
  93. unsigned int colorimetry;
  94. unsigned int pix_repet_factor;
  95. unsigned int hdcp_enable;
  96. struct hdmi_vmode video_mode;
  97. };
  98. struct imx_hdmi {
  99. struct drm_connector connector;
  100. struct drm_encoder encoder;
  101. enum imx_hdmi_devtype dev_type;
  102. struct device *dev;
  103. struct clk *isfr_clk;
  104. struct clk *iahb_clk;
  105. struct hdmi_data_info hdmi_data;
  106. int vic;
  107. u8 edid[HDMI_EDID_LEN];
  108. bool cable_plugin;
  109. bool phy_enabled;
  110. struct drm_display_mode previous_mode;
  111. struct regmap *regmap;
  112. struct i2c_adapter *ddc;
  113. void __iomem *regs;
  114. unsigned int sample_rate;
  115. int ratio;
  116. };
  117. static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
  118. {
  119. regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
  120. IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
  121. ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
  122. }
  123. static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
  124. {
  125. writeb(val, hdmi->regs + offset);
  126. }
  127. static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
  128. {
  129. return readb(hdmi->regs + offset);
  130. }
  131. static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
  132. {
  133. u8 val = hdmi_readb(hdmi, reg) & ~mask;
  134. val |= data & mask;
  135. hdmi_writeb(hdmi, val, reg);
  136. }
  137. static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
  138. u8 shift, u8 mask)
  139. {
  140. hdmi_modb(hdmi, data << shift, mask, reg);
  141. }
  142. static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
  143. unsigned int value)
  144. {
  145. hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
  146. hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
  147. hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);
  148. /* nshift factor = 0 */
  149. hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
  150. }
  151. static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
  152. {
  153. /* Must be set/cleared first */
  154. hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
  155. hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
  156. hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
  157. hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
  158. HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
  159. }
  160. static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
  161. unsigned int ratio)
  162. {
  163. unsigned int n = (128 * freq) / 1000;
  164. switch (freq) {
  165. case 32000:
  166. if (pixel_clk == 25170000)
  167. n = (ratio == 150) ? 9152 : 4576;
  168. else if (pixel_clk == 27020000)
  169. n = (ratio == 150) ? 8192 : 4096;
  170. else if (pixel_clk == 74170000 || pixel_clk == 148350000)
  171. n = 11648;
  172. else
  173. n = 4096;
  174. break;
  175. case 44100:
  176. if (pixel_clk == 25170000)
  177. n = 7007;
  178. else if (pixel_clk == 74170000)
  179. n = 17836;
  180. else if (pixel_clk == 148350000)
  181. n = (ratio == 150) ? 17836 : 8918;
  182. else
  183. n = 6272;
  184. break;
  185. case 48000:
  186. if (pixel_clk == 25170000)
  187. n = (ratio == 150) ? 9152 : 6864;
  188. else if (pixel_clk == 27020000)
  189. n = (ratio == 150) ? 8192 : 6144;
  190. else if (pixel_clk == 74170000)
  191. n = 11648;
  192. else if (pixel_clk == 148350000)
  193. n = (ratio == 150) ? 11648 : 5824;
  194. else
  195. n = 6144;
  196. break;
  197. case 88200:
  198. n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
  199. break;
  200. case 96000:
  201. n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
  202. break;
  203. case 176400:
  204. n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
  205. break;
  206. case 192000:
  207. n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
  208. break;
  209. default:
  210. break;
  211. }
  212. return n;
  213. }
  214. static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
  215. unsigned int ratio)
  216. {
  217. unsigned int cts = 0;
  218. pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
  219. pixel_clk, ratio);
  220. switch (freq) {
  221. case 32000:
  222. if (pixel_clk == 297000000) {
  223. cts = 222750;
  224. break;
  225. }
  226. case 48000:
  227. case 96000:
  228. case 192000:
  229. switch (pixel_clk) {
  230. case 25200000:
  231. case 27000000:
  232. case 54000000:
  233. case 74250000:
  234. case 148500000:
  235. cts = pixel_clk / 1000;
  236. break;
  237. case 297000000:
  238. cts = 247500;
  239. break;
  240. /*
  241. * All other TMDS clocks are not supported by
  242. * DWC_hdmi_tx. The TMDS clocks divided or
  243. * multiplied by 1,001 coefficients are not
  244. * supported.
  245. */
  246. default:
  247. break;
  248. }
  249. break;
  250. case 44100:
  251. case 88200:
  252. case 176400:
  253. switch (pixel_clk) {
  254. case 25200000:
  255. cts = 28000;
  256. break;
  257. case 27000000:
  258. cts = 30000;
  259. break;
  260. case 54000000:
  261. cts = 60000;
  262. break;
  263. case 74250000:
  264. cts = 82500;
  265. break;
  266. case 148500000:
  267. cts = 165000;
  268. break;
  269. case 297000000:
  270. cts = 247500;
  271. break;
  272. default:
  273. break;
  274. }
  275. break;
  276. default:
  277. break;
  278. }
  279. if (ratio == 100)
  280. return cts;
  281. return (cts * ratio) / 100;
  282. }
  283. static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
  284. unsigned long pixel_clk)
  285. {
  286. unsigned int clk_n, clk_cts;
  287. clk_n = hdmi_compute_n(hdmi->sample_rate, pixel_clk,
  288. hdmi->ratio);
  289. clk_cts = hdmi_compute_cts(hdmi->sample_rate, pixel_clk,
  290. hdmi->ratio);
  291. if (!clk_cts) {
  292. dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
  293. __func__, pixel_clk);
  294. return;
  295. }
  296. dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n",
  297. __func__, hdmi->sample_rate, hdmi->ratio,
  298. pixel_clk, clk_n, clk_cts);
  299. hdmi_set_clock_regenerator_n(hdmi, clk_n);
  300. hdmi_regenerate_cts(hdmi, clk_cts);
  301. }
  302. static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
  303. {
  304. hdmi_set_clk_regenerator(hdmi, 74250000);
  305. }
  306. static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
  307. {
  308. hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
  309. }
  310. /*
  311. * this submodule is responsible for the video data synchronization.
  312. * for example, for RGB 4:4:4 input, the data map is defined as
  313. * pin{47~40} <==> R[7:0]
  314. * pin{31~24} <==> G[7:0]
  315. * pin{15~8} <==> B[7:0]
  316. */
  317. static void hdmi_video_sample(struct imx_hdmi *hdmi)
  318. {
  319. int color_format = 0;
  320. u8 val;
  321. if (hdmi->hdmi_data.enc_in_format == RGB) {
  322. if (hdmi->hdmi_data.enc_color_depth == 8)
  323. color_format = 0x01;
  324. else if (hdmi->hdmi_data.enc_color_depth == 10)
  325. color_format = 0x03;
  326. else if (hdmi->hdmi_data.enc_color_depth == 12)
  327. color_format = 0x05;
  328. else if (hdmi->hdmi_data.enc_color_depth == 16)
  329. color_format = 0x07;
  330. else
  331. return;
  332. } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
  333. if (hdmi->hdmi_data.enc_color_depth == 8)
  334. color_format = 0x09;
  335. else if (hdmi->hdmi_data.enc_color_depth == 10)
  336. color_format = 0x0B;
  337. else if (hdmi->hdmi_data.enc_color_depth == 12)
  338. color_format = 0x0D;
  339. else if (hdmi->hdmi_data.enc_color_depth == 16)
  340. color_format = 0x0F;
  341. else
  342. return;
  343. } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
  344. if (hdmi->hdmi_data.enc_color_depth == 8)
  345. color_format = 0x16;
  346. else if (hdmi->hdmi_data.enc_color_depth == 10)
  347. color_format = 0x14;
  348. else if (hdmi->hdmi_data.enc_color_depth == 12)
  349. color_format = 0x12;
  350. else
  351. return;
  352. }
  353. val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
  354. ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
  355. HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
  356. hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
  357. /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
  358. val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
  359. HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
  360. HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
  361. hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
  362. hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
  363. hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
  364. hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
  365. hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
  366. hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
  367. hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
  368. }
  369. static int is_color_space_conversion(struct imx_hdmi *hdmi)
  370. {
  371. return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
  372. }
  373. static int is_color_space_decimation(struct imx_hdmi *hdmi)
  374. {
  375. if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
  376. return 0;
  377. if (hdmi->hdmi_data.enc_in_format == RGB ||
  378. hdmi->hdmi_data.enc_in_format == YCBCR444)
  379. return 1;
  380. return 0;
  381. }
  382. static int is_color_space_interpolation(struct imx_hdmi *hdmi)
  383. {
  384. if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
  385. return 0;
  386. if (hdmi->hdmi_data.enc_out_format == RGB ||
  387. hdmi->hdmi_data.enc_out_format == YCBCR444)
  388. return 1;
  389. return 0;
  390. }
  391. static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
  392. {
  393. const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
  394. unsigned i;
  395. u32 csc_scale = 1;
  396. if (is_color_space_conversion(hdmi)) {
  397. if (hdmi->hdmi_data.enc_out_format == RGB) {
  398. if (hdmi->hdmi_data.colorimetry ==
  399. HDMI_COLORIMETRY_ITU_601)
  400. csc_coeff = &csc_coeff_rgb_out_eitu601;
  401. else
  402. csc_coeff = &csc_coeff_rgb_out_eitu709;
  403. } else if (hdmi->hdmi_data.enc_in_format == RGB) {
  404. if (hdmi->hdmi_data.colorimetry ==
  405. HDMI_COLORIMETRY_ITU_601)
  406. csc_coeff = &csc_coeff_rgb_in_eitu601;
  407. else
  408. csc_coeff = &csc_coeff_rgb_in_eitu709;
  409. csc_scale = 0;
  410. }
  411. }
  412. /* The CSC registers are sequential, alternating MSB then LSB */
  413. for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
  414. u16 coeff_a = (*csc_coeff)[0][i];
  415. u16 coeff_b = (*csc_coeff)[1][i];
  416. u16 coeff_c = (*csc_coeff)[2][i];
  417. hdmi_writeb(hdmi, coeff_a & 0xff,
  418. HDMI_CSC_COEF_A1_LSB + i * 2);
  419. hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
  420. hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
  421. hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
  422. hdmi_writeb(hdmi, coeff_c & 0xff,
  423. HDMI_CSC_COEF_C1_LSB + i * 2);
  424. hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
  425. }
  426. hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
  427. HDMI_CSC_SCALE);
  428. }
  429. static void hdmi_video_csc(struct imx_hdmi *hdmi)
  430. {
  431. int color_depth = 0;
  432. int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
  433. int decimation = 0;
  434. /* YCC422 interpolation to 444 mode */
  435. if (is_color_space_interpolation(hdmi))
  436. interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
  437. else if (is_color_space_decimation(hdmi))
  438. decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
  439. if (hdmi->hdmi_data.enc_color_depth == 8)
  440. color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
  441. else if (hdmi->hdmi_data.enc_color_depth == 10)
  442. color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
  443. else if (hdmi->hdmi_data.enc_color_depth == 12)
  444. color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
  445. else if (hdmi->hdmi_data.enc_color_depth == 16)
  446. color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
  447. else
  448. return;
  449. /* Configure the CSC registers */
  450. hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
  451. hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
  452. HDMI_CSC_SCALE);
  453. imx_hdmi_update_csc_coeffs(hdmi);
  454. }
  455. /*
  456. * HDMI video packetizer is used to packetize the data.
  457. * for example, if input is YCC422 mode or repeater is used,
  458. * data should be repacked this module can be bypassed.
  459. */
  460. static void hdmi_video_packetize(struct imx_hdmi *hdmi)
  461. {
  462. unsigned int color_depth = 0;
  463. unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
  464. unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
  465. struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
  466. u8 val, vp_conf;
  467. if (hdmi_data->enc_out_format == RGB
  468. || hdmi_data->enc_out_format == YCBCR444) {
  469. if (!hdmi_data->enc_color_depth)
  470. output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  471. else if (hdmi_data->enc_color_depth == 8) {
  472. color_depth = 4;
  473. output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
  474. } else if (hdmi_data->enc_color_depth == 10)
  475. color_depth = 5;
  476. else if (hdmi_data->enc_color_depth == 12)
  477. color_depth = 6;
  478. else if (hdmi_data->enc_color_depth == 16)
  479. color_depth = 7;
  480. else
  481. return;
  482. } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
  483. if (!hdmi_data->enc_color_depth ||
  484. hdmi_data->enc_color_depth == 8)
  485. remap_size = HDMI_VP_REMAP_YCC422_16bit;
  486. else if (hdmi_data->enc_color_depth == 10)
  487. remap_size = HDMI_VP_REMAP_YCC422_20bit;
  488. else if (hdmi_data->enc_color_depth == 12)
  489. remap_size = HDMI_VP_REMAP_YCC422_24bit;
  490. else
  491. return;
  492. output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
  493. } else
  494. return;
  495. /* set the packetizer registers */
  496. val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
  497. HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
  498. ((hdmi_data->pix_repet_factor <<
  499. HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
  500. HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
  501. hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
  502. hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
  503. HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
  504. /* Data from pixel repeater block */
  505. if (hdmi_data->pix_repet_factor > 1) {
  506. vp_conf = HDMI_VP_CONF_PR_EN_ENABLE |
  507. HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
  508. } else { /* data from packetizer block */
  509. vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
  510. HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
  511. }
  512. hdmi_modb(hdmi, vp_conf,
  513. HDMI_VP_CONF_PR_EN_MASK |
  514. HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
  515. hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
  516. HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
  517. hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
  518. if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
  519. vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
  520. HDMI_VP_CONF_PP_EN_ENABLE |
  521. HDMI_VP_CONF_YCC422_EN_DISABLE;
  522. } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
  523. vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
  524. HDMI_VP_CONF_PP_EN_DISABLE |
  525. HDMI_VP_CONF_YCC422_EN_ENABLE;
  526. } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
  527. vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
  528. HDMI_VP_CONF_PP_EN_DISABLE |
  529. HDMI_VP_CONF_YCC422_EN_DISABLE;
  530. } else {
  531. return;
  532. }
  533. hdmi_modb(hdmi, vp_conf,
  534. HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK |
  535. HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF);
  536. hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
  537. HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE,
  538. HDMI_VP_STUFF_PP_STUFFING_MASK |
  539. HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF);
  540. hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
  541. HDMI_VP_CONF);
  542. }
  543. static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
  544. unsigned char bit)
  545. {
  546. hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
  547. HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
  548. }
  549. static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
  550. unsigned char bit)
  551. {
  552. hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
  553. HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
  554. }
  555. static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
  556. unsigned char bit)
  557. {
  558. hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
  559. HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
  560. }
  561. static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
  562. unsigned char bit)
  563. {
  564. hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
  565. }
  566. static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
  567. unsigned char bit)
  568. {
  569. hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
  570. }
  571. static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
  572. {
  573. while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
  574. if (msec-- == 0)
  575. return false;
  576. udelay(1000);
  577. }
  578. return true;
  579. }
  580. static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
  581. unsigned char addr)
  582. {
  583. hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
  584. hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
  585. hdmi_writeb(hdmi, (unsigned char)(data >> 8),
  586. HDMI_PHY_I2CM_DATAO_1_ADDR);
  587. hdmi_writeb(hdmi, (unsigned char)(data >> 0),
  588. HDMI_PHY_I2CM_DATAO_0_ADDR);
  589. hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
  590. HDMI_PHY_I2CM_OPERATION_ADDR);
  591. hdmi_phy_wait_i2c_done(hdmi, 1000);
  592. }
  593. static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
  594. unsigned char addr)
  595. {
  596. __hdmi_phy_i2c_write(hdmi, data, addr);
  597. return 0;
  598. }
  599. static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
  600. {
  601. hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
  602. HDMI_PHY_CONF0_PDZ_OFFSET,
  603. HDMI_PHY_CONF0_PDZ_MASK);
  604. }
  605. static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
  606. {
  607. hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
  608. HDMI_PHY_CONF0_ENTMDS_OFFSET,
  609. HDMI_PHY_CONF0_ENTMDS_MASK);
  610. }
  611. static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
  612. {
  613. hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
  614. HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
  615. HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
  616. }
  617. static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
  618. {
  619. hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
  620. HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
  621. HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
  622. }
  623. static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
  624. {
  625. hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
  626. HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
  627. HDMI_PHY_CONF0_SELDATAENPOL_MASK);
  628. }
  629. static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
  630. {
  631. hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
  632. HDMI_PHY_CONF0_SELDIPIF_OFFSET,
  633. HDMI_PHY_CONF0_SELDIPIF_MASK);
  634. }
  635. enum {
  636. RES_8,
  637. RES_10,
  638. RES_12,
  639. RES_MAX,
  640. };
  641. struct mpll_config {
  642. unsigned long mpixelclock;
  643. struct {
  644. u16 cpce;
  645. u16 gmp;
  646. } res[RES_MAX];
  647. };
  648. static const struct mpll_config mpll_config[] = {
  649. {
  650. 45250000, {
  651. { 0x01e0, 0x0000 },
  652. { 0x21e1, 0x0000 },
  653. { 0x41e2, 0x0000 }
  654. },
  655. }, {
  656. 92500000, {
  657. { 0x0140, 0x0005 },
  658. { 0x2141, 0x0005 },
  659. { 0x4142, 0x0005 },
  660. },
  661. }, {
  662. 148500000, {
  663. { 0x00a0, 0x000a },
  664. { 0x20a1, 0x000a },
  665. { 0x40a2, 0x000a },
  666. },
  667. }, {
  668. ~0UL, {
  669. { 0x00a0, 0x000a },
  670. { 0x2001, 0x000f },
  671. { 0x4002, 0x000f },
  672. },
  673. }
  674. };
  675. struct curr_ctrl {
  676. unsigned long mpixelclock;
  677. u16 curr[RES_MAX];
  678. };
  679. static const struct curr_ctrl curr_ctrl[] = {
  680. /* pixelclk bpp8 bpp10 bpp12 */
  681. {
  682. 54000000, { 0x091c, 0x091c, 0x06dc },
  683. }, {
  684. 58400000, { 0x091c, 0x06dc, 0x06dc },
  685. }, {
  686. 72000000, { 0x06dc, 0x06dc, 0x091c },
  687. }, {
  688. 74250000, { 0x06dc, 0x0b5c, 0x091c },
  689. }, {
  690. 118800000, { 0x091c, 0x091c, 0x06dc },
  691. }, {
  692. 216000000, { 0x06dc, 0x0b5c, 0x091c },
  693. }
  694. };
  695. static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
  696. unsigned char res, int cscon)
  697. {
  698. unsigned res_idx, i;
  699. u8 val, msec;
  700. if (prep)
  701. return -EINVAL;
  702. switch (res) {
  703. case 0: /* color resolution 0 is 8 bit colour depth */
  704. case 8:
  705. res_idx = RES_8;
  706. break;
  707. case 10:
  708. res_idx = RES_10;
  709. break;
  710. case 12:
  711. res_idx = RES_12;
  712. break;
  713. default:
  714. return -EINVAL;
  715. }
  716. /* Enable csc path */
  717. if (cscon)
  718. val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
  719. else
  720. val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
  721. hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
  722. /* gen2 tx power off */
  723. imx_hdmi_phy_gen2_txpwron(hdmi, 0);
  724. /* gen2 pddq */
  725. imx_hdmi_phy_gen2_pddq(hdmi, 1);
  726. /* PHY reset */
  727. hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
  728. hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
  729. hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
  730. hdmi_phy_test_clear(hdmi, 1);
  731. hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
  732. HDMI_PHY_I2CM_SLAVE_ADDR);
  733. hdmi_phy_test_clear(hdmi, 0);
  734. /* PLL/MPLL Cfg - always match on final entry */
  735. for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
  736. if (hdmi->hdmi_data.video_mode.mpixelclock <=
  737. mpll_config[i].mpixelclock)
  738. break;
  739. hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
  740. hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
  741. for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
  742. if (hdmi->hdmi_data.video_mode.mpixelclock <=
  743. curr_ctrl[i].mpixelclock)
  744. break;
  745. if (i >= ARRAY_SIZE(curr_ctrl)) {
  746. dev_err(hdmi->dev,
  747. "Pixel clock %d - unsupported by HDMI\n",
  748. hdmi->hdmi_data.video_mode.mpixelclock);
  749. return -EINVAL;
  750. }
  751. /* CURRCTRL */
  752. hdmi_phy_i2c_write(hdmi, curr_ctrl[i].curr[res_idx], 0x10);
  753. hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
  754. hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
  755. /* RESISTANCE TERM 133Ohm Cfg */
  756. hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
  757. /* PREEMP Cgf 0.00 */
  758. hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
  759. /* TX/CK LVL 10 */
  760. hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
  761. /* REMOVE CLK TERM */
  762. hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
  763. imx_hdmi_phy_enable_power(hdmi, 1);
  764. /* toggle TMDS enable */
  765. imx_hdmi_phy_enable_tmds(hdmi, 0);
  766. imx_hdmi_phy_enable_tmds(hdmi, 1);
  767. /* gen2 tx power on */
  768. imx_hdmi_phy_gen2_txpwron(hdmi, 1);
  769. imx_hdmi_phy_gen2_pddq(hdmi, 0);
  770. /*Wait for PHY PLL lock */
  771. msec = 5;
  772. do {
  773. val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
  774. if (!val)
  775. break;
  776. if (msec == 0) {
  777. dev_err(hdmi->dev, "PHY PLL not locked\n");
  778. return -ETIMEDOUT;
  779. }
  780. udelay(1000);
  781. msec--;
  782. } while (1);
  783. return 0;
  784. }
  785. static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
  786. {
  787. int i, ret;
  788. bool cscon = false;
  789. /*check csc whether needed activated in HDMI mode */
  790. cscon = (is_color_space_conversion(hdmi) &&
  791. !hdmi->hdmi_data.video_mode.mdvi);
  792. /* HDMI Phy spec says to do the phy initialization sequence twice */
  793. for (i = 0; i < 2; i++) {
  794. imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
  795. imx_hdmi_phy_sel_interface_control(hdmi, 0);
  796. imx_hdmi_phy_enable_tmds(hdmi, 0);
  797. imx_hdmi_phy_enable_power(hdmi, 0);
  798. /* Enable CSC */
  799. ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
  800. if (ret)
  801. return ret;
  802. }
  803. hdmi->phy_enabled = true;
  804. return 0;
  805. }
  806. static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
  807. {
  808. u8 de;
  809. if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
  810. de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
  811. else
  812. de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
  813. /* disable rx detect */
  814. hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
  815. HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
  816. hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
  817. hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
  818. HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
  819. }
  820. static void hdmi_config_AVI(struct imx_hdmi *hdmi)
  821. {
  822. u8 val, pix_fmt, under_scan;
  823. u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
  824. bool aspect_16_9;
  825. aspect_16_9 = false; /* FIXME */
  826. /* AVI Data Byte 1 */
  827. if (hdmi->hdmi_data.enc_out_format == YCBCR444)
  828. pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
  829. else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
  830. pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
  831. else
  832. pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
  833. under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
  834. /*
  835. * Active format identification data is present in the AVI InfoFrame.
  836. * Under scan info, no bar data
  837. */
  838. val = pix_fmt | under_scan |
  839. HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
  840. HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
  841. hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
  842. /* AVI Data Byte 2 -Set the Aspect Ratio */
  843. if (aspect_16_9) {
  844. act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
  845. coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
  846. } else {
  847. act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
  848. coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
  849. }
  850. /* Set up colorimetry */
  851. if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
  852. colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
  853. if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
  854. ext_colorimetry =
  855. HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  856. else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
  857. ext_colorimetry =
  858. HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
  859. } else if (hdmi->hdmi_data.enc_out_format != RGB) {
  860. if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
  861. colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
  862. else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
  863. colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
  864. ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  865. } else { /* Carries no data */
  866. colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
  867. ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
  868. }
  869. val = colorimetry | coded_ratio | act_ratio;
  870. hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
  871. /* AVI Data Byte 3 */
  872. val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
  873. HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
  874. HDMI_FC_AVICONF2_SCALING_NONE;
  875. hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
  876. /* AVI Data Byte 4 */
  877. hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID);
  878. /* AVI Data Byte 5- set up input and output pixel repetition */
  879. val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
  880. HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
  881. HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
  882. ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
  883. HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
  884. HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
  885. hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
  886. /* IT Content and quantization range = don't care */
  887. val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
  888. HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
  889. hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
  890. /* AVI Data Bytes 6-13 */
  891. hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0);
  892. hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1);
  893. hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0);
  894. hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1);
  895. hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0);
  896. hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1);
  897. hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0);
  898. hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
  899. }
  900. static void hdmi_av_composer(struct imx_hdmi *hdmi,
  901. const struct drm_display_mode *mode)
  902. {
  903. u8 inv_val;
  904. struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
  905. int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
  906. vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC);
  907. vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC);
  908. vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
  909. vmode->mpixelclock = mode->clock * 1000;
  910. dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
  911. /* Set up HDMI_FC_INVIDCONF */
  912. inv_val = (hdmi->hdmi_data.hdcp_enable ?
  913. HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
  914. HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
  915. inv_val |= (vmode->mvsyncpolarity ?
  916. HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
  917. HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
  918. inv_val |= (vmode->mhsyncpolarity ?
  919. HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
  920. HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
  921. inv_val |= (vmode->mdataenablepolarity ?
  922. HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
  923. HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
  924. if (hdmi->vic == 39)
  925. inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
  926. else
  927. inv_val |= (vmode->minterlaced ?
  928. HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
  929. HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
  930. inv_val |= (vmode->minterlaced ?
  931. HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
  932. HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
  933. inv_val |= (vmode->mdvi ?
  934. HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
  935. HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
  936. hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
  937. /* Set up horizontal active pixel width */
  938. hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
  939. hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
  940. /* Set up vertical active lines */
  941. hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
  942. hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
  943. /* Set up horizontal blanking pixel region width */
  944. hblank = mode->htotal - mode->hdisplay;
  945. hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
  946. hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
  947. /* Set up vertical blanking pixel region width */
  948. vblank = mode->vtotal - mode->vdisplay;
  949. hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
  950. /* Set up HSYNC active edge delay width (in pixel clks) */
  951. h_de_hs = mode->hsync_start - mode->hdisplay;
  952. hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
  953. hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
  954. /* Set up VSYNC active edge delay (in lines) */
  955. v_de_vs = mode->vsync_start - mode->vdisplay;
  956. hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
  957. /* Set up HSYNC active pulse width (in pixel clks) */
  958. hsync_len = mode->hsync_end - mode->hsync_start;
  959. hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
  960. hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
  961. /* Set up VSYNC active edge delay (in lines) */
  962. vsync_len = mode->vsync_end - mode->vsync_start;
  963. hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
  964. }
  965. static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
  966. {
  967. if (!hdmi->phy_enabled)
  968. return;
  969. imx_hdmi_phy_enable_tmds(hdmi, 0);
  970. imx_hdmi_phy_enable_power(hdmi, 0);
  971. hdmi->phy_enabled = false;
  972. }
  973. /* HDMI Initialization Step B.4 */
  974. static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
  975. {
  976. u8 clkdis;
  977. /* control period minimum duration */
  978. hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
  979. hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
  980. hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
  981. /* Set to fill TMDS data channels */
  982. hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
  983. hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
  984. hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
  985. /* Enable pixel clock and tmds data path */
  986. clkdis = 0x7F;
  987. clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
  988. hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
  989. clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
  990. hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
  991. /* Enable csc path */
  992. if (is_color_space_conversion(hdmi)) {
  993. clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
  994. hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
  995. }
  996. }
  997. static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
  998. {
  999. hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
  1000. }
  1001. /* Workaround to clear the overflow condition */
  1002. static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
  1003. {
  1004. int count;
  1005. u8 val;
  1006. /* TMDS software reset */
  1007. hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
  1008. val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
  1009. if (hdmi->dev_type == IMX6DL_HDMI) {
  1010. hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
  1011. return;
  1012. }
  1013. for (count = 0; count < 4; count++)
  1014. hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
  1015. }
  1016. static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
  1017. {
  1018. hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
  1019. hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
  1020. }
  1021. static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
  1022. {
  1023. hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
  1024. HDMI_IH_MUTE_FC_STAT2);
  1025. }
  1026. static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
  1027. {
  1028. int ret;
  1029. hdmi_disable_overflow_interrupts(hdmi);
  1030. hdmi->vic = drm_match_cea_mode(mode);
  1031. if (!hdmi->vic) {
  1032. dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
  1033. hdmi->hdmi_data.video_mode.mdvi = true;
  1034. } else {
  1035. dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
  1036. hdmi->hdmi_data.video_mode.mdvi = false;
  1037. }
  1038. if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
  1039. (hdmi->vic == 21) || (hdmi->vic == 22) ||
  1040. (hdmi->vic == 2) || (hdmi->vic == 3) ||
  1041. (hdmi->vic == 17) || (hdmi->vic == 18))
  1042. hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
  1043. else
  1044. hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
  1045. if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
  1046. (hdmi->vic == 12) || (hdmi->vic == 13) ||
  1047. (hdmi->vic == 14) || (hdmi->vic == 15) ||
  1048. (hdmi->vic == 25) || (hdmi->vic == 26) ||
  1049. (hdmi->vic == 27) || (hdmi->vic == 28) ||
  1050. (hdmi->vic == 29) || (hdmi->vic == 30) ||
  1051. (hdmi->vic == 35) || (hdmi->vic == 36) ||
  1052. (hdmi->vic == 37) || (hdmi->vic == 38))
  1053. hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
  1054. else
  1055. hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
  1056. hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
  1057. /* TODO: Get input format from IPU (via FB driver interface) */
  1058. hdmi->hdmi_data.enc_in_format = RGB;
  1059. hdmi->hdmi_data.enc_out_format = RGB;
  1060. hdmi->hdmi_data.enc_color_depth = 8;
  1061. hdmi->hdmi_data.pix_repet_factor = 0;
  1062. hdmi->hdmi_data.hdcp_enable = 0;
  1063. hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
  1064. /* HDMI Initialization Step B.1 */
  1065. hdmi_av_composer(hdmi, mode);
  1066. /* HDMI Initializateion Step B.2 */
  1067. ret = imx_hdmi_phy_init(hdmi);
  1068. if (ret)
  1069. return ret;
  1070. /* HDMI Initialization Step B.3 */
  1071. imx_hdmi_enable_video_path(hdmi);
  1072. /* not for DVI mode */
  1073. if (hdmi->hdmi_data.video_mode.mdvi)
  1074. dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
  1075. else {
  1076. dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
  1077. /* HDMI Initialization Step E - Configure audio */
  1078. hdmi_clk_regenerator_update_pixel_clock(hdmi);
  1079. hdmi_enable_audio_clk(hdmi);
  1080. /* HDMI Initialization Step F - Configure AVI InfoFrame */
  1081. hdmi_config_AVI(hdmi);
  1082. }
  1083. hdmi_video_packetize(hdmi);
  1084. hdmi_video_csc(hdmi);
  1085. hdmi_video_sample(hdmi);
  1086. hdmi_tx_hdcp_config(hdmi);
  1087. imx_hdmi_clear_overflow(hdmi);
  1088. if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
  1089. hdmi_enable_overflow_interrupts(hdmi);
  1090. return 0;
  1091. }
  1092. /* Wait until we are registered to enable interrupts */
  1093. static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
  1094. {
  1095. hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
  1096. HDMI_PHY_I2CM_INT_ADDR);
  1097. hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
  1098. HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
  1099. HDMI_PHY_I2CM_CTLINT_ADDR);
  1100. /* enable cable hot plug irq */
  1101. hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
  1102. /* Clear Hotplug interrupts */
  1103. hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
  1104. return 0;
  1105. }
  1106. static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
  1107. {
  1108. u8 ih_mute;
  1109. /*
  1110. * Boot up defaults are:
  1111. * HDMI_IH_MUTE = 0x03 (disabled)
  1112. * HDMI_IH_MUTE_* = 0x00 (enabled)
  1113. *
  1114. * Disable top level interrupt bits in HDMI block
  1115. */
  1116. ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) |
  1117. HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  1118. HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
  1119. hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
  1120. /* by default mask all interrupts */
  1121. hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK);
  1122. hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0);
  1123. hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1);
  1124. hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2);
  1125. hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0);
  1126. hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR);
  1127. hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
  1128. hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT);
  1129. hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT);
  1130. hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
  1131. hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
  1132. hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
  1133. hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
  1134. hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
  1135. hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
  1136. /* Disable interrupts in the IH_MUTE_* registers */
  1137. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
  1138. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
  1139. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
  1140. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
  1141. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0);
  1142. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
  1143. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
  1144. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
  1145. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
  1146. hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
  1147. /* Enable top level interrupt bits in HDMI block */
  1148. ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
  1149. HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
  1150. hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
  1151. }
  1152. static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
  1153. {
  1154. imx_hdmi_setup(hdmi, &hdmi->previous_mode);
  1155. }
  1156. static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
  1157. {
  1158. imx_hdmi_phy_disable(hdmi);
  1159. }
  1160. static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
  1161. *connector, bool force)
  1162. {
  1163. struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
  1164. connector);
  1165. return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
  1166. connector_status_connected : connector_status_disconnected;
  1167. }
  1168. static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
  1169. {
  1170. struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
  1171. connector);
  1172. struct edid *edid;
  1173. int ret;
  1174. if (!hdmi->ddc)
  1175. return 0;
  1176. edid = drm_get_edid(connector, hdmi->ddc);
  1177. if (edid) {
  1178. dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
  1179. edid->width_cm, edid->height_cm);
  1180. drm_mode_connector_update_edid_property(connector, edid);
  1181. ret = drm_add_edid_modes(connector, edid);
  1182. kfree(edid);
  1183. } else {
  1184. dev_dbg(hdmi->dev, "failed to get edid\n");
  1185. }
  1186. return 0;
  1187. }
  1188. static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
  1189. *connector)
  1190. {
  1191. struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
  1192. connector);
  1193. return &hdmi->encoder;
  1194. }
  1195. static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
  1196. struct drm_display_mode *mode,
  1197. struct drm_display_mode *adjusted_mode)
  1198. {
  1199. struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
  1200. imx_hdmi_setup(hdmi, mode);
  1201. /* Store the display mode for plugin/DKMS poweron events */
  1202. memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
  1203. }
  1204. static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
  1205. const struct drm_display_mode *mode,
  1206. struct drm_display_mode *adjusted_mode)
  1207. {
  1208. return true;
  1209. }
  1210. static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
  1211. {
  1212. }
  1213. static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
  1214. {
  1215. struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
  1216. if (mode)
  1217. imx_hdmi_poweroff(hdmi);
  1218. else
  1219. imx_hdmi_poweron(hdmi);
  1220. }
  1221. static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
  1222. {
  1223. struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
  1224. imx_hdmi_poweroff(hdmi);
  1225. imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
  1226. }
  1227. static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
  1228. {
  1229. struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
  1230. int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
  1231. imx_hdmi_set_ipu_di_mux(hdmi, mux);
  1232. imx_hdmi_poweron(hdmi);
  1233. }
  1234. static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
  1235. .destroy = imx_drm_encoder_destroy,
  1236. };
  1237. static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
  1238. .dpms = imx_hdmi_encoder_dpms,
  1239. .prepare = imx_hdmi_encoder_prepare,
  1240. .commit = imx_hdmi_encoder_commit,
  1241. .mode_set = imx_hdmi_encoder_mode_set,
  1242. .mode_fixup = imx_hdmi_encoder_mode_fixup,
  1243. .disable = imx_hdmi_encoder_disable,
  1244. };
  1245. static struct drm_connector_funcs imx_hdmi_connector_funcs = {
  1246. .dpms = drm_helper_connector_dpms,
  1247. .fill_modes = drm_helper_probe_single_connector_modes,
  1248. .detect = imx_hdmi_connector_detect,
  1249. .destroy = imx_drm_connector_destroy,
  1250. };
  1251. static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
  1252. .get_modes = imx_hdmi_connector_get_modes,
  1253. .best_encoder = imx_hdmi_connector_best_encoder,
  1254. };
  1255. static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
  1256. {
  1257. struct imx_hdmi *hdmi = dev_id;
  1258. u8 intr_stat;
  1259. intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
  1260. if (intr_stat)
  1261. hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
  1262. return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
  1263. }
  1264. static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
  1265. {
  1266. struct imx_hdmi *hdmi = dev_id;
  1267. u8 intr_stat;
  1268. u8 phy_int_pol;
  1269. intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
  1270. phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
  1271. if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
  1272. if (phy_int_pol & HDMI_PHY_HPD) {
  1273. dev_dbg(hdmi->dev, "EVENT=plugin\n");
  1274. hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
  1275. imx_hdmi_poweron(hdmi);
  1276. } else {
  1277. dev_dbg(hdmi->dev, "EVENT=plugout\n");
  1278. hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
  1279. HDMI_PHY_POL0);
  1280. imx_hdmi_poweroff(hdmi);
  1281. }
  1282. drm_helper_hpd_irq_event(hdmi->connector.dev);
  1283. }
  1284. hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
  1285. hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
  1286. return IRQ_HANDLED;
  1287. }
  1288. static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
  1289. {
  1290. int ret;
  1291. ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
  1292. hdmi->dev->of_node);
  1293. if (ret)
  1294. return ret;
  1295. hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
  1296. drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
  1297. drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
  1298. DRM_MODE_ENCODER_TMDS);
  1299. drm_connector_helper_add(&hdmi->connector,
  1300. &imx_hdmi_connector_helper_funcs);
  1301. drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
  1302. DRM_MODE_CONNECTOR_HDMIA);
  1303. hdmi->connector.encoder = &hdmi->encoder;
  1304. drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
  1305. return 0;
  1306. }
  1307. static struct platform_device_id imx_hdmi_devtype[] = {
  1308. {
  1309. .name = "imx6q-hdmi",
  1310. .driver_data = IMX6Q_HDMI,
  1311. }, {
  1312. .name = "imx6dl-hdmi",
  1313. .driver_data = IMX6DL_HDMI,
  1314. }, { /* sentinel */ }
  1315. };
  1316. MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
  1317. static const struct of_device_id imx_hdmi_dt_ids[] = {
  1318. { .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
  1319. { .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
  1320. { /* sentinel */ }
  1321. };
  1322. MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
  1323. static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
  1324. {
  1325. struct platform_device *pdev = to_platform_device(dev);
  1326. const struct of_device_id *of_id =
  1327. of_match_device(imx_hdmi_dt_ids, dev);
  1328. struct drm_device *drm = data;
  1329. struct device_node *np = dev->of_node;
  1330. struct device_node *ddc_node;
  1331. struct imx_hdmi *hdmi;
  1332. struct resource *iores;
  1333. int ret, irq;
  1334. hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
  1335. if (!hdmi)
  1336. return -ENOMEM;
  1337. hdmi->dev = dev;
  1338. hdmi->sample_rate = 48000;
  1339. hdmi->ratio = 100;
  1340. if (of_id) {
  1341. const struct platform_device_id *device_id = of_id->data;
  1342. hdmi->dev_type = device_id->driver_data;
  1343. }
  1344. ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
  1345. if (ddc_node) {
  1346. hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
  1347. if (!hdmi->ddc)
  1348. dev_dbg(hdmi->dev, "failed to read ddc node\n");
  1349. of_node_put(ddc_node);
  1350. } else {
  1351. dev_dbg(hdmi->dev, "no ddc property found\n");
  1352. }
  1353. irq = platform_get_irq(pdev, 0);
  1354. if (irq < 0)
  1355. return irq;
  1356. ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
  1357. imx_hdmi_irq, IRQF_SHARED,
  1358. dev_name(dev), hdmi);
  1359. if (ret)
  1360. return ret;
  1361. iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1362. hdmi->regs = devm_ioremap_resource(dev, iores);
  1363. if (IS_ERR(hdmi->regs))
  1364. return PTR_ERR(hdmi->regs);
  1365. hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
  1366. if (IS_ERR(hdmi->regmap))
  1367. return PTR_ERR(hdmi->regmap);
  1368. hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
  1369. if (IS_ERR(hdmi->isfr_clk)) {
  1370. ret = PTR_ERR(hdmi->isfr_clk);
  1371. dev_err(hdmi->dev,
  1372. "Unable to get HDMI isfr clk: %d\n", ret);
  1373. return ret;
  1374. }
  1375. ret = clk_prepare_enable(hdmi->isfr_clk);
  1376. if (ret) {
  1377. dev_err(hdmi->dev,
  1378. "Cannot enable HDMI isfr clock: %d\n", ret);
  1379. return ret;
  1380. }
  1381. hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
  1382. if (IS_ERR(hdmi->iahb_clk)) {
  1383. ret = PTR_ERR(hdmi->iahb_clk);
  1384. dev_err(hdmi->dev,
  1385. "Unable to get HDMI iahb clk: %d\n", ret);
  1386. goto err_isfr;
  1387. }
  1388. ret = clk_prepare_enable(hdmi->iahb_clk);
  1389. if (ret) {
  1390. dev_err(hdmi->dev,
  1391. "Cannot enable HDMI iahb clock: %d\n", ret);
  1392. goto err_isfr;
  1393. }
  1394. /* Product and revision IDs */
  1395. dev_info(dev,
  1396. "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
  1397. hdmi_readb(hdmi, HDMI_DESIGN_ID),
  1398. hdmi_readb(hdmi, HDMI_REVISION_ID),
  1399. hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
  1400. hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
  1401. initialize_hdmi_ih_mutes(hdmi);
  1402. /*
  1403. * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
  1404. * N and cts values before enabling phy
  1405. */
  1406. hdmi_init_clk_regenerator(hdmi);
  1407. /*
  1408. * Configure registers related to HDMI interrupt
  1409. * generation before registering IRQ.
  1410. */
  1411. hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
  1412. /* Clear Hotplug interrupts */
  1413. hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
  1414. ret = imx_hdmi_fb_registered(hdmi);
  1415. if (ret)
  1416. goto err_iahb;
  1417. ret = imx_hdmi_register(drm, hdmi);
  1418. if (ret)
  1419. goto err_iahb;
  1420. /* Unmute interrupts */
  1421. hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
  1422. dev_set_drvdata(dev, hdmi);
  1423. return 0;
  1424. err_iahb:
  1425. clk_disable_unprepare(hdmi->iahb_clk);
  1426. err_isfr:
  1427. clk_disable_unprepare(hdmi->isfr_clk);
  1428. return ret;
  1429. }
  1430. static void imx_hdmi_unbind(struct device *dev, struct device *master,
  1431. void *data)
  1432. {
  1433. struct imx_hdmi *hdmi = dev_get_drvdata(dev);
  1434. /* Disable all interrupts */
  1435. hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
  1436. hdmi->connector.funcs->destroy(&hdmi->connector);
  1437. hdmi->encoder.funcs->destroy(&hdmi->encoder);
  1438. clk_disable_unprepare(hdmi->iahb_clk);
  1439. clk_disable_unprepare(hdmi->isfr_clk);
  1440. i2c_put_adapter(hdmi->ddc);
  1441. }
  1442. static const struct component_ops hdmi_ops = {
  1443. .bind = imx_hdmi_bind,
  1444. .unbind = imx_hdmi_unbind,
  1445. };
  1446. static int imx_hdmi_platform_probe(struct platform_device *pdev)
  1447. {
  1448. return component_add(&pdev->dev, &hdmi_ops);
  1449. }
  1450. static int imx_hdmi_platform_remove(struct platform_device *pdev)
  1451. {
  1452. component_del(&pdev->dev, &hdmi_ops);
  1453. return 0;
  1454. }
  1455. static struct platform_driver imx_hdmi_driver = {
  1456. .probe = imx_hdmi_platform_probe,
  1457. .remove = imx_hdmi_platform_remove,
  1458. .driver = {
  1459. .name = "imx-hdmi",
  1460. .of_match_table = imx_hdmi_dt_ids,
  1461. },
  1462. };
  1463. module_platform_driver(imx_hdmi_driver);
  1464. MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
  1465. MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
  1466. MODULE_LICENSE("GPL");
  1467. MODULE_ALIAS("platform:imx-hdmi");