meson_venc.c 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2016 BayLibre, SAS
  4. * Author: Neil Armstrong <narmstrong@baylibre.com>
  5. * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
  6. */
  7. #include <linux/export.h>
  8. #include <drm/drm_modes.h>
  9. #include "meson_drv.h"
  10. #include "meson_registers.h"
  11. #include "meson_venc.h"
  12. #include "meson_vpp.h"
  13. /**
  14. * DOC: Video Encoder
  15. *
  16. * VENC Handle the pixels encoding to the output formats.
  17. * We handle the following encodings :
  18. *
  19. * - CVBS Encoding via the ENCI encoder and VDAC digital to analog converter
  20. * - TMDS/HDMI Encoding via ENCI_DIV and ENCP
  21. * - Setup of more clock rates for HDMI modes
  22. *
  23. * What is missing :
  24. *
  25. * - LCD Panel encoding via ENCL
  26. * - TV Panel encoding via ENCT
  27. *
  28. * VENC paths :
  29. *
  30. * .. code::
  31. *
  32. * _____ _____ ____________________
  33. * vd1---| |-| | | VENC /---------|----VDAC
  34. * vd2---| VIU |-| VPP |-|-----ENCI/-ENCI_DVI-|-|
  35. * osd1--| |-| | | \ | X--HDMI-TX
  36. * osd2--|_____|-|_____| | |\-ENCP--ENCP_DVI-|-|
  37. * | | |
  38. * | \--ENCL-----------|----LVDS
  39. * |____________________|
  40. *
  41. * The ENCI is designed for PAl or NTSC encoding and can go through the VDAC
  42. * directly for CVBS encoding or through the ENCI_DVI encoder for HDMI.
  43. * The ENCP is designed for Progressive encoding but can also generate
  44. * 1080i interlaced pixels, and was initialy desined to encode pixels for
  45. * VDAC to output RGB ou YUV analog outputs.
  46. * It's output is only used through the ENCP_DVI encoder for HDMI.
  47. * The ENCL LVDS encoder is not implemented.
  48. *
  49. * The ENCI and ENCP encoders needs specially defined parameters for each
  50. * supported mode and thus cannot be determined from standard video timings.
  51. *
  52. * The ENCI end ENCP DVI encoders are more generic and can generate any timings
  53. * from the pixel data generated by ENCI or ENCP, so can use the standard video
  54. * timings are source for HW parameters.
  55. */
  56. /* HHI Registers */
  57. #define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
  58. #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
  59. #define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */
  60. #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
  61. #define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */
  62. #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
  63. struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
  64. .mode_tag = MESON_VENC_MODE_CVBS_PAL,
  65. .hso_begin = 3,
  66. .hso_end = 129,
  67. .vso_even = 3,
  68. .vso_odd = 260,
  69. .macv_max_amp = 7,
  70. .video_prog_mode = 0xff,
  71. .video_mode = 0x13,
  72. .sch_adjust = 0x28,
  73. .yc_delay = 0x343,
  74. .pixel_start = 251,
  75. .pixel_end = 1691,
  76. .top_field_line_start = 22,
  77. .top_field_line_end = 310,
  78. .bottom_field_line_start = 23,
  79. .bottom_field_line_end = 311,
  80. .video_saturation = 9,
  81. .video_contrast = 0,
  82. .video_brightness = 0,
  83. .video_hue = 0,
  84. .analog_sync_adj = 0x8080,
  85. };
  86. struct meson_cvbs_enci_mode meson_cvbs_enci_ntsc = {
  87. .mode_tag = MESON_VENC_MODE_CVBS_NTSC,
  88. .hso_begin = 5,
  89. .hso_end = 129,
  90. .vso_even = 3,
  91. .vso_odd = 260,
  92. .macv_max_amp = 0xb,
  93. .video_prog_mode = 0xf0,
  94. .video_mode = 0x8,
  95. .sch_adjust = 0x20,
  96. .yc_delay = 0x333,
  97. .pixel_start = 227,
  98. .pixel_end = 1667,
  99. .top_field_line_start = 18,
  100. .top_field_line_end = 258,
  101. .bottom_field_line_start = 19,
  102. .bottom_field_line_end = 259,
  103. .video_saturation = 18,
  104. .video_contrast = 3,
  105. .video_brightness = 0,
  106. .video_hue = 0,
  107. .analog_sync_adj = 0x9c00,
  108. };
  109. union meson_hdmi_venc_mode {
  110. struct {
  111. unsigned int mode_tag;
  112. unsigned int hso_begin;
  113. unsigned int hso_end;
  114. unsigned int vso_even;
  115. unsigned int vso_odd;
  116. unsigned int macv_max_amp;
  117. unsigned int video_prog_mode;
  118. unsigned int video_mode;
  119. unsigned int sch_adjust;
  120. unsigned int yc_delay;
  121. unsigned int pixel_start;
  122. unsigned int pixel_end;
  123. unsigned int top_field_line_start;
  124. unsigned int top_field_line_end;
  125. unsigned int bottom_field_line_start;
  126. unsigned int bottom_field_line_end;
  127. } enci;
  128. struct {
  129. unsigned int dvi_settings;
  130. unsigned int video_mode;
  131. unsigned int video_mode_adv;
  132. unsigned int video_prog_mode;
  133. bool video_prog_mode_present;
  134. unsigned int video_sync_mode;
  135. bool video_sync_mode_present;
  136. unsigned int video_yc_dly;
  137. bool video_yc_dly_present;
  138. unsigned int video_rgb_ctrl;
  139. bool video_rgb_ctrl_present;
  140. unsigned int video_filt_ctrl;
  141. bool video_filt_ctrl_present;
  142. unsigned int video_ofld_voav_ofst;
  143. bool video_ofld_voav_ofst_present;
  144. unsigned int yfp1_htime;
  145. unsigned int yfp2_htime;
  146. unsigned int max_pxcnt;
  147. unsigned int hspuls_begin;
  148. unsigned int hspuls_end;
  149. unsigned int hspuls_switch;
  150. unsigned int vspuls_begin;
  151. unsigned int vspuls_end;
  152. unsigned int vspuls_bline;
  153. unsigned int vspuls_eline;
  154. unsigned int eqpuls_begin;
  155. bool eqpuls_begin_present;
  156. unsigned int eqpuls_end;
  157. bool eqpuls_end_present;
  158. unsigned int eqpuls_bline;
  159. bool eqpuls_bline_present;
  160. unsigned int eqpuls_eline;
  161. bool eqpuls_eline_present;
  162. unsigned int havon_begin;
  163. unsigned int havon_end;
  164. unsigned int vavon_bline;
  165. unsigned int vavon_eline;
  166. unsigned int hso_begin;
  167. unsigned int hso_end;
  168. unsigned int vso_begin;
  169. unsigned int vso_end;
  170. unsigned int vso_bline;
  171. unsigned int vso_eline;
  172. bool vso_eline_present;
  173. unsigned int sy_val;
  174. bool sy_val_present;
  175. unsigned int sy2_val;
  176. bool sy2_val_present;
  177. unsigned int max_lncnt;
  178. } encp;
  179. };
  180. union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
  181. .enci = {
  182. .hso_begin = 5,
  183. .hso_end = 129,
  184. .vso_even = 3,
  185. .vso_odd = 260,
  186. .macv_max_amp = 0xb,
  187. .video_prog_mode = 0xf0,
  188. .video_mode = 0x8,
  189. .sch_adjust = 0x20,
  190. .yc_delay = 0,
  191. .pixel_start = 227,
  192. .pixel_end = 1667,
  193. .top_field_line_start = 18,
  194. .top_field_line_end = 258,
  195. .bottom_field_line_start = 19,
  196. .bottom_field_line_end = 259,
  197. },
  198. };
  199. union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
  200. .enci = {
  201. .hso_begin = 3,
  202. .hso_end = 129,
  203. .vso_even = 3,
  204. .vso_odd = 260,
  205. .macv_max_amp = 0x7,
  206. .video_prog_mode = 0xff,
  207. .video_mode = 0x13,
  208. .sch_adjust = 0x28,
  209. .yc_delay = 0x333,
  210. .pixel_start = 251,
  211. .pixel_end = 1691,
  212. .top_field_line_start = 22,
  213. .top_field_line_end = 310,
  214. .bottom_field_line_start = 23,
  215. .bottom_field_line_end = 311,
  216. },
  217. };
  218. union meson_hdmi_venc_mode meson_hdmi_encp_mode_480p = {
  219. .encp = {
  220. .dvi_settings = 0x21,
  221. .video_mode = 0x4000,
  222. .video_mode_adv = 0x9,
  223. .video_prog_mode = 0,
  224. .video_prog_mode_present = true,
  225. .video_sync_mode = 7,
  226. .video_sync_mode_present = true,
  227. /* video_yc_dly */
  228. /* video_rgb_ctrl */
  229. .video_filt_ctrl = 0x2052,
  230. .video_filt_ctrl_present = true,
  231. /* video_ofld_voav_ofst */
  232. .yfp1_htime = 244,
  233. .yfp2_htime = 1630,
  234. .max_pxcnt = 1715,
  235. .hspuls_begin = 0x22,
  236. .hspuls_end = 0xa0,
  237. .hspuls_switch = 88,
  238. .vspuls_begin = 0,
  239. .vspuls_end = 1589,
  240. .vspuls_bline = 0,
  241. .vspuls_eline = 5,
  242. .havon_begin = 249,
  243. .havon_end = 1689,
  244. .vavon_bline = 42,
  245. .vavon_eline = 521,
  246. /* eqpuls_begin */
  247. /* eqpuls_end */
  248. /* eqpuls_bline */
  249. /* eqpuls_eline */
  250. .hso_begin = 3,
  251. .hso_end = 5,
  252. .vso_begin = 3,
  253. .vso_end = 5,
  254. .vso_bline = 0,
  255. /* vso_eline */
  256. .sy_val = 8,
  257. .sy_val_present = true,
  258. .sy2_val = 0x1d8,
  259. .sy2_val_present = true,
  260. .max_lncnt = 524,
  261. },
  262. };
  263. union meson_hdmi_venc_mode meson_hdmi_encp_mode_576p = {
  264. .encp = {
  265. .dvi_settings = 0x21,
  266. .video_mode = 0x4000,
  267. .video_mode_adv = 0x9,
  268. .video_prog_mode = 0,
  269. .video_prog_mode_present = true,
  270. .video_sync_mode = 7,
  271. .video_sync_mode_present = true,
  272. /* video_yc_dly */
  273. /* video_rgb_ctrl */
  274. .video_filt_ctrl = 0x52,
  275. .video_filt_ctrl_present = true,
  276. /* video_ofld_voav_ofst */
  277. .yfp1_htime = 235,
  278. .yfp2_htime = 1674,
  279. .max_pxcnt = 1727,
  280. .hspuls_begin = 0,
  281. .hspuls_end = 0x80,
  282. .hspuls_switch = 88,
  283. .vspuls_begin = 0,
  284. .vspuls_end = 1599,
  285. .vspuls_bline = 0,
  286. .vspuls_eline = 4,
  287. .havon_begin = 235,
  288. .havon_end = 1674,
  289. .vavon_bline = 44,
  290. .vavon_eline = 619,
  291. /* eqpuls_begin */
  292. /* eqpuls_end */
  293. /* eqpuls_bline */
  294. /* eqpuls_eline */
  295. .hso_begin = 0x80,
  296. .hso_end = 0,
  297. .vso_begin = 0,
  298. .vso_end = 5,
  299. .vso_bline = 0,
  300. /* vso_eline */
  301. .sy_val = 8,
  302. .sy_val_present = true,
  303. .sy2_val = 0x1d8,
  304. .sy2_val_present = true,
  305. .max_lncnt = 624,
  306. },
  307. };
  308. union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p60 = {
  309. .encp = {
  310. .dvi_settings = 0x2029,
  311. .video_mode = 0x4040,
  312. .video_mode_adv = 0x19,
  313. /* video_prog_mode */
  314. /* video_sync_mode */
  315. /* video_yc_dly */
  316. /* video_rgb_ctrl */
  317. /* video_filt_ctrl */
  318. /* video_ofld_voav_ofst */
  319. .yfp1_htime = 648,
  320. .yfp2_htime = 3207,
  321. .max_pxcnt = 3299,
  322. .hspuls_begin = 80,
  323. .hspuls_end = 240,
  324. .hspuls_switch = 80,
  325. .vspuls_begin = 688,
  326. .vspuls_end = 3248,
  327. .vspuls_bline = 4,
  328. .vspuls_eline = 8,
  329. .havon_begin = 648,
  330. .havon_end = 3207,
  331. .vavon_bline = 29,
  332. .vavon_eline = 748,
  333. /* eqpuls_begin */
  334. /* eqpuls_end */
  335. /* eqpuls_bline */
  336. /* eqpuls_eline */
  337. .hso_begin = 256,
  338. .hso_end = 168,
  339. .vso_begin = 168,
  340. .vso_end = 256,
  341. .vso_bline = 0,
  342. .vso_eline = 5,
  343. .vso_eline_present = true,
  344. /* sy_val */
  345. /* sy2_val */
  346. .max_lncnt = 749,
  347. },
  348. };
  349. union meson_hdmi_venc_mode meson_hdmi_encp_mode_720p50 = {
  350. .encp = {
  351. .dvi_settings = 0x202d,
  352. .video_mode = 0x4040,
  353. .video_mode_adv = 0x19,
  354. .video_prog_mode = 0x100,
  355. .video_prog_mode_present = true,
  356. .video_sync_mode = 0x407,
  357. .video_sync_mode_present = true,
  358. .video_yc_dly = 0,
  359. .video_yc_dly_present = true,
  360. /* video_rgb_ctrl */
  361. /* video_filt_ctrl */
  362. /* video_ofld_voav_ofst */
  363. .yfp1_htime = 648,
  364. .yfp2_htime = 3207,
  365. .max_pxcnt = 3959,
  366. .hspuls_begin = 80,
  367. .hspuls_end = 240,
  368. .hspuls_switch = 80,
  369. .vspuls_begin = 688,
  370. .vspuls_end = 3248,
  371. .vspuls_bline = 4,
  372. .vspuls_eline = 8,
  373. .havon_begin = 648,
  374. .havon_end = 3207,
  375. .vavon_bline = 29,
  376. .vavon_eline = 748,
  377. /* eqpuls_begin */
  378. /* eqpuls_end */
  379. /* eqpuls_bline */
  380. /* eqpuls_eline */
  381. .hso_begin = 128,
  382. .hso_end = 208,
  383. .vso_begin = 128,
  384. .vso_end = 128,
  385. .vso_bline = 0,
  386. .vso_eline = 5,
  387. .vso_eline_present = true,
  388. /* sy_val */
  389. /* sy2_val */
  390. .max_lncnt = 749,
  391. },
  392. };
  393. union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i60 = {
  394. .encp = {
  395. .dvi_settings = 0x2029,
  396. .video_mode = 0x5ffc,
  397. .video_mode_adv = 0x19,
  398. .video_prog_mode = 0x100,
  399. .video_prog_mode_present = true,
  400. .video_sync_mode = 0x207,
  401. .video_sync_mode_present = true,
  402. /* video_yc_dly */
  403. /* video_rgb_ctrl */
  404. /* video_filt_ctrl */
  405. .video_ofld_voav_ofst = 0x11,
  406. .video_ofld_voav_ofst_present = true,
  407. .yfp1_htime = 516,
  408. .yfp2_htime = 4355,
  409. .max_pxcnt = 4399,
  410. .hspuls_begin = 88,
  411. .hspuls_end = 264,
  412. .hspuls_switch = 88,
  413. .vspuls_begin = 440,
  414. .vspuls_end = 2200,
  415. .vspuls_bline = 0,
  416. .vspuls_eline = 4,
  417. .havon_begin = 516,
  418. .havon_end = 4355,
  419. .vavon_bline = 20,
  420. .vavon_eline = 559,
  421. .eqpuls_begin = 2288,
  422. .eqpuls_begin_present = true,
  423. .eqpuls_end = 2464,
  424. .eqpuls_end_present = true,
  425. .eqpuls_bline = 0,
  426. .eqpuls_bline_present = true,
  427. .eqpuls_eline = 4,
  428. .eqpuls_eline_present = true,
  429. .hso_begin = 264,
  430. .hso_end = 176,
  431. .vso_begin = 88,
  432. .vso_end = 88,
  433. .vso_bline = 0,
  434. .vso_eline = 5,
  435. .vso_eline_present = true,
  436. /* sy_val */
  437. /* sy2_val */
  438. .max_lncnt = 1124,
  439. },
  440. };
  441. union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080i50 = {
  442. .encp = {
  443. .dvi_settings = 0x202d,
  444. .video_mode = 0x5ffc,
  445. .video_mode_adv = 0x19,
  446. .video_prog_mode = 0x100,
  447. .video_prog_mode_present = true,
  448. .video_sync_mode = 0x7,
  449. .video_sync_mode_present = true,
  450. /* video_yc_dly */
  451. /* video_rgb_ctrl */
  452. /* video_filt_ctrl */
  453. .video_ofld_voav_ofst = 0x11,
  454. .video_ofld_voav_ofst_present = true,
  455. .yfp1_htime = 526,
  456. .yfp2_htime = 4365,
  457. .max_pxcnt = 5279,
  458. .hspuls_begin = 88,
  459. .hspuls_end = 264,
  460. .hspuls_switch = 88,
  461. .vspuls_begin = 440,
  462. .vspuls_end = 2200,
  463. .vspuls_bline = 0,
  464. .vspuls_eline = 4,
  465. .havon_begin = 526,
  466. .havon_end = 4365,
  467. .vavon_bline = 20,
  468. .vavon_eline = 559,
  469. .eqpuls_begin = 2288,
  470. .eqpuls_begin_present = true,
  471. .eqpuls_end = 2464,
  472. .eqpuls_end_present = true,
  473. .eqpuls_bline = 0,
  474. .eqpuls_bline_present = true,
  475. .eqpuls_eline = 4,
  476. .eqpuls_eline_present = true,
  477. .hso_begin = 142,
  478. .hso_end = 230,
  479. .vso_begin = 142,
  480. .vso_end = 142,
  481. .vso_bline = 0,
  482. .vso_eline = 5,
  483. .vso_eline_present = true,
  484. /* sy_val */
  485. /* sy2_val */
  486. .max_lncnt = 1124,
  487. },
  488. };
  489. union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p24 = {
  490. .encp = {
  491. .dvi_settings = 0xd,
  492. .video_mode = 0x4040,
  493. .video_mode_adv = 0x18,
  494. .video_prog_mode = 0x100,
  495. .video_prog_mode_present = true,
  496. .video_sync_mode = 0x7,
  497. .video_sync_mode_present = true,
  498. .video_yc_dly = 0,
  499. .video_yc_dly_present = true,
  500. .video_rgb_ctrl = 2,
  501. .video_rgb_ctrl_present = true,
  502. .video_filt_ctrl = 0x1052,
  503. .video_filt_ctrl_present = true,
  504. /* video_ofld_voav_ofst */
  505. .yfp1_htime = 271,
  506. .yfp2_htime = 2190,
  507. .max_pxcnt = 2749,
  508. .hspuls_begin = 44,
  509. .hspuls_end = 132,
  510. .hspuls_switch = 44,
  511. .vspuls_begin = 220,
  512. .vspuls_end = 2140,
  513. .vspuls_bline = 0,
  514. .vspuls_eline = 4,
  515. .havon_begin = 271,
  516. .havon_end = 2190,
  517. .vavon_bline = 41,
  518. .vavon_eline = 1120,
  519. /* eqpuls_begin */
  520. /* eqpuls_end */
  521. .eqpuls_bline = 0,
  522. .eqpuls_bline_present = true,
  523. .eqpuls_eline = 4,
  524. .eqpuls_eline_present = true,
  525. .hso_begin = 79,
  526. .hso_end = 123,
  527. .vso_begin = 79,
  528. .vso_end = 79,
  529. .vso_bline = 0,
  530. .vso_eline = 5,
  531. .vso_eline_present = true,
  532. /* sy_val */
  533. /* sy2_val */
  534. .max_lncnt = 1124,
  535. },
  536. };
  537. union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p30 = {
  538. .encp = {
  539. .dvi_settings = 0x1,
  540. .video_mode = 0x4040,
  541. .video_mode_adv = 0x18,
  542. .video_prog_mode = 0x100,
  543. .video_prog_mode_present = true,
  544. /* video_sync_mode */
  545. /* video_yc_dly */
  546. /* video_rgb_ctrl */
  547. .video_filt_ctrl = 0x1052,
  548. .video_filt_ctrl_present = true,
  549. /* video_ofld_voav_ofst */
  550. .yfp1_htime = 140,
  551. .yfp2_htime = 2060,
  552. .max_pxcnt = 2199,
  553. .hspuls_begin = 2156,
  554. .hspuls_end = 44,
  555. .hspuls_switch = 44,
  556. .vspuls_begin = 140,
  557. .vspuls_end = 2059,
  558. .vspuls_bline = 0,
  559. .vspuls_eline = 4,
  560. .havon_begin = 148,
  561. .havon_end = 2067,
  562. .vavon_bline = 41,
  563. .vavon_eline = 1120,
  564. /* eqpuls_begin */
  565. /* eqpuls_end */
  566. /* eqpuls_bline */
  567. /* eqpuls_eline */
  568. .hso_begin = 44,
  569. .hso_end = 2156,
  570. .vso_begin = 2100,
  571. .vso_end = 2164,
  572. .vso_bline = 0,
  573. .vso_eline = 5,
  574. .vso_eline_present = true,
  575. /* sy_val */
  576. /* sy2_val */
  577. .max_lncnt = 1124,
  578. },
  579. };
  580. union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p50 = {
  581. .encp = {
  582. .dvi_settings = 0xd,
  583. .video_mode = 0x4040,
  584. .video_mode_adv = 0x18,
  585. .video_prog_mode = 0x100,
  586. .video_prog_mode_present = true,
  587. .video_sync_mode = 0x7,
  588. .video_sync_mode_present = true,
  589. .video_yc_dly = 0,
  590. .video_yc_dly_present = true,
  591. .video_rgb_ctrl = 2,
  592. .video_rgb_ctrl_present = true,
  593. /* video_filt_ctrl */
  594. /* video_ofld_voav_ofst */
  595. .yfp1_htime = 271,
  596. .yfp2_htime = 2190,
  597. .max_pxcnt = 2639,
  598. .hspuls_begin = 44,
  599. .hspuls_end = 132,
  600. .hspuls_switch = 44,
  601. .vspuls_begin = 220,
  602. .vspuls_end = 2140,
  603. .vspuls_bline = 0,
  604. .vspuls_eline = 4,
  605. .havon_begin = 271,
  606. .havon_end = 2190,
  607. .vavon_bline = 41,
  608. .vavon_eline = 1120,
  609. /* eqpuls_begin */
  610. /* eqpuls_end */
  611. .eqpuls_bline = 0,
  612. .eqpuls_bline_present = true,
  613. .eqpuls_eline = 4,
  614. .eqpuls_eline_present = true,
  615. .hso_begin = 79,
  616. .hso_end = 123,
  617. .vso_begin = 79,
  618. .vso_end = 79,
  619. .vso_bline = 0,
  620. .vso_eline = 5,
  621. .vso_eline_present = true,
  622. /* sy_val */
  623. /* sy2_val */
  624. .max_lncnt = 1124,
  625. },
  626. };
  627. union meson_hdmi_venc_mode meson_hdmi_encp_mode_1080p60 = {
  628. .encp = {
  629. .dvi_settings = 0x1,
  630. .video_mode = 0x4040,
  631. .video_mode_adv = 0x18,
  632. .video_prog_mode = 0x100,
  633. .video_prog_mode_present = true,
  634. /* video_sync_mode */
  635. /* video_yc_dly */
  636. /* video_rgb_ctrl */
  637. .video_filt_ctrl = 0x1052,
  638. .video_filt_ctrl_present = true,
  639. /* video_ofld_voav_ofst */
  640. .yfp1_htime = 140,
  641. .yfp2_htime = 2060,
  642. .max_pxcnt = 2199,
  643. .hspuls_begin = 2156,
  644. .hspuls_end = 44,
  645. .hspuls_switch = 44,
  646. .vspuls_begin = 140,
  647. .vspuls_end = 2059,
  648. .vspuls_bline = 0,
  649. .vspuls_eline = 4,
  650. .havon_begin = 148,
  651. .havon_end = 2067,
  652. .vavon_bline = 41,
  653. .vavon_eline = 1120,
  654. /* eqpuls_begin */
  655. /* eqpuls_end */
  656. /* eqpuls_bline */
  657. /* eqpuls_eline */
  658. .hso_begin = 44,
  659. .hso_end = 2156,
  660. .vso_begin = 2100,
  661. .vso_end = 2164,
  662. .vso_bline = 0,
  663. .vso_eline = 5,
  664. .vso_eline_present = true,
  665. /* sy_val */
  666. /* sy2_val */
  667. .max_lncnt = 1124,
  668. },
  669. };
  670. union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p24 = {
  671. .encp = {
  672. .dvi_settings = 0x1,
  673. .video_mode = 0x4040,
  674. .video_mode_adv = 0x8,
  675. /* video_sync_mode */
  676. /* video_yc_dly */
  677. /* video_rgb_ctrl */
  678. .video_filt_ctrl = 0x1000,
  679. .video_filt_ctrl_present = true,
  680. /* video_ofld_voav_ofst */
  681. .yfp1_htime = 140,
  682. .yfp2_htime = 140+3840,
  683. .max_pxcnt = 3840+1660-1,
  684. .hspuls_begin = 2156+1920,
  685. .hspuls_end = 44,
  686. .hspuls_switch = 44,
  687. .vspuls_begin = 140,
  688. .vspuls_end = 2059+1920,
  689. .vspuls_bline = 0,
  690. .vspuls_eline = 4,
  691. .havon_begin = 148,
  692. .havon_end = 3987,
  693. .vavon_bline = 89,
  694. .vavon_eline = 2248,
  695. /* eqpuls_begin */
  696. /* eqpuls_end */
  697. /* eqpuls_bline */
  698. /* eqpuls_eline */
  699. .hso_begin = 44,
  700. .hso_end = 2156+1920,
  701. .vso_begin = 2100+1920,
  702. .vso_end = 2164+1920,
  703. .vso_bline = 51,
  704. .vso_eline = 53,
  705. .vso_eline_present = true,
  706. /* sy_val */
  707. /* sy2_val */
  708. .max_lncnt = 2249,
  709. },
  710. };
  711. union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p25 = {
  712. .encp = {
  713. .dvi_settings = 0x1,
  714. .video_mode = 0x4040,
  715. .video_mode_adv = 0x8,
  716. /* video_sync_mode */
  717. /* video_yc_dly */
  718. /* video_rgb_ctrl */
  719. .video_filt_ctrl = 0x1000,
  720. .video_filt_ctrl_present = true,
  721. /* video_ofld_voav_ofst */
  722. .yfp1_htime = 140,
  723. .yfp2_htime = 140+3840,
  724. .max_pxcnt = 3840+1440-1,
  725. .hspuls_begin = 2156+1920,
  726. .hspuls_end = 44,
  727. .hspuls_switch = 44,
  728. .vspuls_begin = 140,
  729. .vspuls_end = 2059+1920,
  730. .vspuls_bline = 0,
  731. .vspuls_eline = 4,
  732. .havon_begin = 148,
  733. .havon_end = 3987,
  734. .vavon_bline = 89,
  735. .vavon_eline = 2248,
  736. /* eqpuls_begin */
  737. /* eqpuls_end */
  738. /* eqpuls_bline */
  739. /* eqpuls_eline */
  740. .hso_begin = 44,
  741. .hso_end = 2156+1920,
  742. .vso_begin = 2100+1920,
  743. .vso_end = 2164+1920,
  744. .vso_bline = 51,
  745. .vso_eline = 53,
  746. .vso_eline_present = true,
  747. /* sy_val */
  748. /* sy2_val */
  749. .max_lncnt = 2249,
  750. },
  751. };
  752. union meson_hdmi_venc_mode meson_hdmi_encp_mode_2160p30 = {
  753. .encp = {
  754. .dvi_settings = 0x1,
  755. .video_mode = 0x4040,
  756. .video_mode_adv = 0x8,
  757. /* video_sync_mode */
  758. /* video_yc_dly */
  759. /* video_rgb_ctrl */
  760. .video_filt_ctrl = 0x1000,
  761. .video_filt_ctrl_present = true,
  762. /* video_ofld_voav_ofst */
  763. .yfp1_htime = 140,
  764. .yfp2_htime = 140+3840,
  765. .max_pxcnt = 3840+560-1,
  766. .hspuls_begin = 2156+1920,
  767. .hspuls_end = 44,
  768. .hspuls_switch = 44,
  769. .vspuls_begin = 140,
  770. .vspuls_end = 2059+1920,
  771. .vspuls_bline = 0,
  772. .vspuls_eline = 4,
  773. .havon_begin = 148,
  774. .havon_end = 3987,
  775. .vavon_bline = 89,
  776. .vavon_eline = 2248,
  777. /* eqpuls_begin */
  778. /* eqpuls_end */
  779. /* eqpuls_bline */
  780. /* eqpuls_eline */
  781. .hso_begin = 44,
  782. .hso_end = 2156+1920,
  783. .vso_begin = 2100+1920,
  784. .vso_end = 2164+1920,
  785. .vso_bline = 51,
  786. .vso_eline = 53,
  787. .vso_eline_present = true,
  788. /* sy_val */
  789. /* sy2_val */
  790. .max_lncnt = 2249,
  791. },
  792. };
  793. struct meson_hdmi_venc_vic_mode {
  794. unsigned int vic;
  795. union meson_hdmi_venc_mode *mode;
  796. } meson_hdmi_venc_vic_modes[] = {
  797. { 6, &meson_hdmi_enci_mode_480i },
  798. { 7, &meson_hdmi_enci_mode_480i },
  799. { 21, &meson_hdmi_enci_mode_576i },
  800. { 22, &meson_hdmi_enci_mode_576i },
  801. { 2, &meson_hdmi_encp_mode_480p },
  802. { 3, &meson_hdmi_encp_mode_480p },
  803. { 17, &meson_hdmi_encp_mode_576p },
  804. { 18, &meson_hdmi_encp_mode_576p },
  805. { 4, &meson_hdmi_encp_mode_720p60 },
  806. { 19, &meson_hdmi_encp_mode_720p50 },
  807. { 5, &meson_hdmi_encp_mode_1080i60 },
  808. { 20, &meson_hdmi_encp_mode_1080i50 },
  809. { 32, &meson_hdmi_encp_mode_1080p24 },
  810. { 33, &meson_hdmi_encp_mode_1080p50 },
  811. { 34, &meson_hdmi_encp_mode_1080p30 },
  812. { 31, &meson_hdmi_encp_mode_1080p50 },
  813. { 16, &meson_hdmi_encp_mode_1080p60 },
  814. { 93, &meson_hdmi_encp_mode_2160p24 },
  815. { 94, &meson_hdmi_encp_mode_2160p25 },
  816. { 95, &meson_hdmi_encp_mode_2160p30 },
  817. { 96, &meson_hdmi_encp_mode_2160p25 },
  818. { 97, &meson_hdmi_encp_mode_2160p30 },
  819. { 0, NULL}, /* sentinel */
  820. };
  821. static signed int to_signed(unsigned int a)
  822. {
  823. if (a <= 7)
  824. return a;
  825. else
  826. return a - 16;
  827. }
  828. static unsigned long modulo(unsigned long a, unsigned long b)
  829. {
  830. if (a >= b)
  831. return a - b;
  832. else
  833. return a;
  834. }
  835. enum drm_mode_status
  836. meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
  837. {
  838. if (mode->flags & ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
  839. DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC))
  840. return MODE_BAD;
  841. if (mode->hdisplay < 640 || mode->hdisplay > 1920)
  842. return MODE_BAD_HVALUE;
  843. if (mode->vdisplay < 480 || mode->vdisplay > 1200)
  844. return MODE_BAD_VVALUE;
  845. return MODE_OK;
  846. }
  847. EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
  848. bool meson_venc_hdmi_supported_vic(int vic)
  849. {
  850. struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
  851. while (vmode->vic && vmode->mode) {
  852. if (vmode->vic == vic)
  853. return true;
  854. vmode++;
  855. }
  856. return false;
  857. }
  858. EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_vic);
  859. void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode,
  860. union meson_hdmi_venc_mode *dmt_mode)
  861. {
  862. memset(dmt_mode, 0, sizeof(*dmt_mode));
  863. dmt_mode->encp.dvi_settings = 0x21;
  864. dmt_mode->encp.video_mode = 0x4040;
  865. dmt_mode->encp.video_mode_adv = 0x18;
  866. dmt_mode->encp.max_pxcnt = mode->htotal - 1;
  867. dmt_mode->encp.havon_begin = mode->htotal - mode->hsync_start;
  868. dmt_mode->encp.havon_end = dmt_mode->encp.havon_begin +
  869. mode->hdisplay - 1;
  870. dmt_mode->encp.vavon_bline = mode->vtotal - mode->vsync_start;
  871. dmt_mode->encp.vavon_eline = dmt_mode->encp.vavon_bline +
  872. mode->vdisplay - 1;
  873. dmt_mode->encp.hso_begin = 0;
  874. dmt_mode->encp.hso_end = mode->hsync_end - mode->hsync_start;
  875. dmt_mode->encp.vso_begin = 30;
  876. dmt_mode->encp.vso_end = 50;
  877. dmt_mode->encp.vso_bline = 0;
  878. dmt_mode->encp.vso_eline = mode->vsync_end - mode->vsync_start;
  879. dmt_mode->encp.vso_eline_present = true;
  880. dmt_mode->encp.max_lncnt = mode->vtotal - 1;
  881. }
  882. static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
  883. {
  884. struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
  885. while (vmode->vic && vmode->mode) {
  886. if (vmode->vic == vic)
  887. return vmode->mode;
  888. vmode++;
  889. }
  890. return NULL;
  891. }
  892. bool meson_venc_hdmi_venc_repeat(int vic)
  893. {
  894. /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
  895. if (vic == 6 || vic == 7 || /* 480i */
  896. vic == 21 || vic == 22 || /* 576i */
  897. vic == 17 || vic == 18 || /* 576p */
  898. vic == 2 || vic == 3 || /* 480p */
  899. vic == 4 || /* 720p60 */
  900. vic == 19 || /* 720p50 */
  901. vic == 5 || /* 1080i60 */
  902. vic == 20) /* 1080i50 */
  903. return true;
  904. return false;
  905. }
  906. EXPORT_SYMBOL_GPL(meson_venc_hdmi_venc_repeat);
  907. void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
  908. unsigned int ycrcb_map,
  909. bool yuv420_mode,
  910. const struct drm_display_mode *mode)
  911. {
  912. union meson_hdmi_venc_mode *vmode = NULL;
  913. union meson_hdmi_venc_mode vmode_dmt;
  914. bool use_enci = false;
  915. bool venc_repeat = false;
  916. bool hdmi_repeat = false;
  917. unsigned int venc_hdmi_latency = 2;
  918. unsigned long total_pixels_venc = 0;
  919. unsigned long active_pixels_venc = 0;
  920. unsigned long front_porch_venc = 0;
  921. unsigned long hsync_pixels_venc = 0;
  922. unsigned long de_h_begin = 0;
  923. unsigned long de_h_end = 0;
  924. unsigned long de_v_begin_even = 0;
  925. unsigned long de_v_end_even = 0;
  926. unsigned long de_v_begin_odd = 0;
  927. unsigned long de_v_end_odd = 0;
  928. unsigned long hs_begin = 0;
  929. unsigned long hs_end = 0;
  930. unsigned long vs_adjust = 0;
  931. unsigned long vs_bline_evn = 0;
  932. unsigned long vs_eline_evn = 0;
  933. unsigned long vs_bline_odd = 0;
  934. unsigned long vs_eline_odd = 0;
  935. unsigned long vso_begin_evn = 0;
  936. unsigned long vso_begin_odd = 0;
  937. unsigned int eof_lines;
  938. unsigned int sof_lines;
  939. unsigned int vsync_lines;
  940. u32 reg;
  941. /* Use VENCI for 480i and 576i and double HDMI pixels */
  942. if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
  943. hdmi_repeat = true;
  944. use_enci = true;
  945. venc_hdmi_latency = 1;
  946. }
  947. if (meson_venc_hdmi_supported_vic(vic)) {
  948. vmode = meson_venc_hdmi_get_vic_vmode(vic);
  949. if (!vmode) {
  950. dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
  951. DRM_MODE_FMT "\n", __func__,
  952. DRM_MODE_ARG(mode));
  953. return;
  954. }
  955. } else {
  956. meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
  957. vmode = &vmode_dmt;
  958. use_enci = false;
  959. }
  960. /* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
  961. if (meson_venc_hdmi_venc_repeat(vic))
  962. venc_repeat = true;
  963. eof_lines = mode->vsync_start - mode->vdisplay;
  964. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  965. eof_lines /= 2;
  966. sof_lines = mode->vtotal - mode->vsync_end;
  967. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  968. sof_lines /= 2;
  969. vsync_lines = mode->vsync_end - mode->vsync_start;
  970. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  971. vsync_lines /= 2;
  972. total_pixels_venc = mode->htotal;
  973. if (hdmi_repeat)
  974. total_pixels_venc /= 2;
  975. if (venc_repeat)
  976. total_pixels_venc *= 2;
  977. active_pixels_venc = mode->hdisplay;
  978. if (hdmi_repeat)
  979. active_pixels_venc /= 2;
  980. if (venc_repeat)
  981. active_pixels_venc *= 2;
  982. front_porch_venc = (mode->hsync_start - mode->hdisplay);
  983. if (hdmi_repeat)
  984. front_porch_venc /= 2;
  985. if (venc_repeat)
  986. front_porch_venc *= 2;
  987. hsync_pixels_venc = (mode->hsync_end - mode->hsync_start);
  988. if (hdmi_repeat)
  989. hsync_pixels_venc /= 2;
  990. if (venc_repeat)
  991. hsync_pixels_venc *= 2;
  992. /* Disable VDACs */
  993. writel_bits_relaxed(0xff, 0xff,
  994. priv->io_base + _REG(VENC_VDAC_SETTING));
  995. writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
  996. writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
  997. if (use_enci) {
  998. unsigned int lines_f0;
  999. unsigned int lines_f1;
  1000. /* CVBS Filter settings */
  1001. writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
  1002. priv->io_base + _REG(ENCI_CFILT_CTRL));
  1003. writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
  1004. ENCI_CFILT_CMPT_CB_DLY(1),
  1005. priv->io_base + _REG(ENCI_CFILT_CTRL2));
  1006. /* Digital Video Select : Interlace, clk27 clk, external */
  1007. writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
  1008. /* Reset Video Mode */
  1009. writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
  1010. writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
  1011. /* Horizontal sync signal output */
  1012. writel_relaxed(vmode->enci.hso_begin,
  1013. priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
  1014. writel_relaxed(vmode->enci.hso_end,
  1015. priv->io_base + _REG(ENCI_SYNC_HSO_END));
  1016. /* Vertical Sync lines */
  1017. writel_relaxed(vmode->enci.vso_even,
  1018. priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
  1019. writel_relaxed(vmode->enci.vso_odd,
  1020. priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
  1021. /* Macrovision max amplitude change */
  1022. writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
  1023. ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp),
  1024. priv->io_base + _REG(ENCI_MACV_MAX_AMP));
  1025. /* Video mode */
  1026. writel_relaxed(vmode->enci.video_prog_mode,
  1027. priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
  1028. writel_relaxed(vmode->enci.video_mode,
  1029. priv->io_base + _REG(ENCI_VIDEO_MODE));
  1030. /*
  1031. * Advanced Video Mode :
  1032. * Demux shifting 0x2
  1033. * Blank line end at line17/22
  1034. * High bandwidth Luma Filter
  1035. * Low bandwidth Chroma Filter
  1036. * Bypass luma low pass filter
  1037. * No macrovision on CSYNC
  1038. */
  1039. writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
  1040. ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
  1041. ENCI_VIDEO_MODE_ADV_YBW_HIGH,
  1042. priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
  1043. writel(vmode->enci.sch_adjust,
  1044. priv->io_base + _REG(ENCI_VIDEO_SCH));
  1045. /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
  1046. writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
  1047. if (vmode->enci.yc_delay)
  1048. writel_relaxed(vmode->enci.yc_delay,
  1049. priv->io_base + _REG(ENCI_YC_DELAY));
  1050. /* UNreset Interlaced TV Encoder */
  1051. writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
  1052. /*
  1053. * Enable Vfifo2vd and set Y_Cb_Y_Cr:
  1054. * Corresponding value:
  1055. * Y => 00 or 10
  1056. * Cb => 01
  1057. * Cr => 11
  1058. * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
  1059. */
  1060. writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
  1061. ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
  1062. priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
  1063. /* Timings */
  1064. writel_relaxed(vmode->enci.pixel_start,
  1065. priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
  1066. writel_relaxed(vmode->enci.pixel_end,
  1067. priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
  1068. writel_relaxed(vmode->enci.top_field_line_start,
  1069. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
  1070. writel_relaxed(vmode->enci.top_field_line_end,
  1071. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
  1072. writel_relaxed(vmode->enci.bottom_field_line_start,
  1073. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
  1074. writel_relaxed(vmode->enci.bottom_field_line_end,
  1075. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
  1076. /* Select ENCI for VIU */
  1077. meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
  1078. /* Interlace video enable */
  1079. writel_relaxed(ENCI_VIDEO_EN_ENABLE,
  1080. priv->io_base + _REG(ENCI_VIDEO_EN));
  1081. lines_f0 = mode->vtotal >> 1;
  1082. lines_f1 = lines_f0 + 1;
  1083. de_h_begin = modulo(readl_relaxed(priv->io_base +
  1084. _REG(ENCI_VFIFO2VD_PIXEL_START))
  1085. + venc_hdmi_latency,
  1086. total_pixels_venc);
  1087. de_h_end = modulo(de_h_begin + active_pixels_venc,
  1088. total_pixels_venc);
  1089. writel_relaxed(de_h_begin,
  1090. priv->io_base + _REG(ENCI_DE_H_BEGIN));
  1091. writel_relaxed(de_h_end,
  1092. priv->io_base + _REG(ENCI_DE_H_END));
  1093. de_v_begin_even = readl_relaxed(priv->io_base +
  1094. _REG(ENCI_VFIFO2VD_LINE_TOP_START));
  1095. de_v_end_even = de_v_begin_even + mode->vdisplay;
  1096. de_v_begin_odd = readl_relaxed(priv->io_base +
  1097. _REG(ENCI_VFIFO2VD_LINE_BOT_START));
  1098. de_v_end_odd = de_v_begin_odd + mode->vdisplay;
  1099. writel_relaxed(de_v_begin_even,
  1100. priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN));
  1101. writel_relaxed(de_v_end_even,
  1102. priv->io_base + _REG(ENCI_DE_V_END_EVEN));
  1103. writel_relaxed(de_v_begin_odd,
  1104. priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD));
  1105. writel_relaxed(de_v_end_odd,
  1106. priv->io_base + _REG(ENCI_DE_V_END_ODD));
  1107. /* Program Hsync timing */
  1108. hs_begin = de_h_end + front_porch_venc;
  1109. if (de_h_end + front_porch_venc >= total_pixels_venc) {
  1110. hs_begin -= total_pixels_venc;
  1111. vs_adjust = 1;
  1112. } else {
  1113. hs_begin = de_h_end + front_porch_venc;
  1114. vs_adjust = 0;
  1115. }
  1116. hs_end = modulo(hs_begin + hsync_pixels_venc,
  1117. total_pixels_venc);
  1118. writel_relaxed(hs_begin,
  1119. priv->io_base + _REG(ENCI_DVI_HSO_BEGIN));
  1120. writel_relaxed(hs_end,
  1121. priv->io_base + _REG(ENCI_DVI_HSO_END));
  1122. /* Program Vsync timing for even field */
  1123. if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) {
  1124. vs_bline_evn = (de_v_end_odd - 1)
  1125. + eof_lines
  1126. + vs_adjust
  1127. - lines_f1;
  1128. vs_eline_evn = vs_bline_evn + vsync_lines;
  1129. writel_relaxed(vs_bline_evn,
  1130. priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
  1131. writel_relaxed(vs_eline_evn,
  1132. priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN));
  1133. writel_relaxed(hs_begin,
  1134. priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN));
  1135. writel_relaxed(hs_begin,
  1136. priv->io_base + _REG(ENCI_DVI_VSO_END_EVN));
  1137. } else {
  1138. vs_bline_odd = (de_v_end_odd - 1)
  1139. + eof_lines
  1140. + vs_adjust;
  1141. writel_relaxed(vs_bline_odd,
  1142. priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
  1143. writel_relaxed(hs_begin,
  1144. priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
  1145. if ((vs_bline_odd + vsync_lines) >= lines_f1) {
  1146. vs_eline_evn = vs_bline_odd
  1147. + vsync_lines
  1148. - lines_f1;
  1149. writel_relaxed(vs_eline_evn, priv->io_base
  1150. + _REG(ENCI_DVI_VSO_ELINE_EVN));
  1151. writel_relaxed(hs_begin, priv->io_base
  1152. + _REG(ENCI_DVI_VSO_END_EVN));
  1153. } else {
  1154. vs_eline_odd = vs_bline_odd
  1155. + vsync_lines;
  1156. writel_relaxed(vs_eline_odd, priv->io_base
  1157. + _REG(ENCI_DVI_VSO_ELINE_ODD));
  1158. writel_relaxed(hs_begin, priv->io_base
  1159. + _REG(ENCI_DVI_VSO_END_ODD));
  1160. }
  1161. }
  1162. /* Program Vsync timing for odd field */
  1163. if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) {
  1164. vs_bline_odd = (de_v_end_even - 1)
  1165. + (eof_lines + 1)
  1166. - lines_f0;
  1167. vs_eline_odd = vs_bline_odd + vsync_lines;
  1168. writel_relaxed(vs_bline_odd,
  1169. priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));
  1170. writel_relaxed(vs_eline_odd,
  1171. priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD));
  1172. vso_begin_odd = modulo(hs_begin
  1173. + (total_pixels_venc >> 1),
  1174. total_pixels_venc);
  1175. writel_relaxed(vso_begin_odd,
  1176. priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
  1177. writel_relaxed(vso_begin_odd,
  1178. priv->io_base + _REG(ENCI_DVI_VSO_END_ODD));
  1179. } else {
  1180. vs_bline_evn = (de_v_end_even - 1)
  1181. + (eof_lines + 1);
  1182. writel_relaxed(vs_bline_evn,
  1183. priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));
  1184. vso_begin_evn = modulo(hs_begin
  1185. + (total_pixels_venc >> 1),
  1186. total_pixels_venc);
  1187. writel_relaxed(vso_begin_evn, priv->io_base
  1188. + _REG(ENCI_DVI_VSO_BEGIN_EVN));
  1189. if (vs_bline_evn + vsync_lines >= lines_f0) {
  1190. vs_eline_odd = vs_bline_evn
  1191. + vsync_lines
  1192. - lines_f0;
  1193. writel_relaxed(vs_eline_odd, priv->io_base
  1194. + _REG(ENCI_DVI_VSO_ELINE_ODD));
  1195. writel_relaxed(vso_begin_evn, priv->io_base
  1196. + _REG(ENCI_DVI_VSO_END_ODD));
  1197. } else {
  1198. vs_eline_evn = vs_bline_evn + vsync_lines;
  1199. writel_relaxed(vs_eline_evn, priv->io_base
  1200. + _REG(ENCI_DVI_VSO_ELINE_EVN));
  1201. writel_relaxed(vso_begin_evn, priv->io_base
  1202. + _REG(ENCI_DVI_VSO_END_EVN));
  1203. }
  1204. }
  1205. } else {
  1206. writel_relaxed(vmode->encp.dvi_settings,
  1207. priv->io_base + _REG(VENC_DVI_SETTING));
  1208. writel_relaxed(vmode->encp.video_mode,
  1209. priv->io_base + _REG(ENCP_VIDEO_MODE));
  1210. writel_relaxed(vmode->encp.video_mode_adv,
  1211. priv->io_base + _REG(ENCP_VIDEO_MODE_ADV));
  1212. if (vmode->encp.video_prog_mode_present)
  1213. writel_relaxed(vmode->encp.video_prog_mode,
  1214. priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
  1215. if (vmode->encp.video_sync_mode_present)
  1216. writel_relaxed(vmode->encp.video_sync_mode,
  1217. priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE));
  1218. if (vmode->encp.video_yc_dly_present)
  1219. writel_relaxed(vmode->encp.video_yc_dly,
  1220. priv->io_base + _REG(ENCP_VIDEO_YC_DLY));
  1221. if (vmode->encp.video_rgb_ctrl_present)
  1222. writel_relaxed(vmode->encp.video_rgb_ctrl,
  1223. priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL));
  1224. if (vmode->encp.video_filt_ctrl_present)
  1225. writel_relaxed(vmode->encp.video_filt_ctrl,
  1226. priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL));
  1227. if (vmode->encp.video_ofld_voav_ofst_present)
  1228. writel_relaxed(vmode->encp.video_ofld_voav_ofst,
  1229. priv->io_base
  1230. + _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
  1231. writel_relaxed(vmode->encp.yfp1_htime,
  1232. priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME));
  1233. writel_relaxed(vmode->encp.yfp2_htime,
  1234. priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME));
  1235. writel_relaxed(vmode->encp.max_pxcnt,
  1236. priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT));
  1237. writel_relaxed(vmode->encp.hspuls_begin,
  1238. priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN));
  1239. writel_relaxed(vmode->encp.hspuls_end,
  1240. priv->io_base + _REG(ENCP_VIDEO_HSPULS_END));
  1241. writel_relaxed(vmode->encp.hspuls_switch,
  1242. priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH));
  1243. writel_relaxed(vmode->encp.vspuls_begin,
  1244. priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN));
  1245. writel_relaxed(vmode->encp.vspuls_end,
  1246. priv->io_base + _REG(ENCP_VIDEO_VSPULS_END));
  1247. writel_relaxed(vmode->encp.vspuls_bline,
  1248. priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE));
  1249. writel_relaxed(vmode->encp.vspuls_eline,
  1250. priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE));
  1251. if (vmode->encp.eqpuls_begin_present)
  1252. writel_relaxed(vmode->encp.eqpuls_begin,
  1253. priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN));
  1254. if (vmode->encp.eqpuls_end_present)
  1255. writel_relaxed(vmode->encp.eqpuls_end,
  1256. priv->io_base + _REG(ENCP_VIDEO_EQPULS_END));
  1257. if (vmode->encp.eqpuls_bline_present)
  1258. writel_relaxed(vmode->encp.eqpuls_bline,
  1259. priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE));
  1260. if (vmode->encp.eqpuls_eline_present)
  1261. writel_relaxed(vmode->encp.eqpuls_eline,
  1262. priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE));
  1263. writel_relaxed(vmode->encp.havon_begin,
  1264. priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN));
  1265. writel_relaxed(vmode->encp.havon_end,
  1266. priv->io_base + _REG(ENCP_VIDEO_HAVON_END));
  1267. writel_relaxed(vmode->encp.vavon_bline,
  1268. priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE));
  1269. writel_relaxed(vmode->encp.vavon_eline,
  1270. priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE));
  1271. writel_relaxed(vmode->encp.hso_begin,
  1272. priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN));
  1273. writel_relaxed(vmode->encp.hso_end,
  1274. priv->io_base + _REG(ENCP_VIDEO_HSO_END));
  1275. writel_relaxed(vmode->encp.vso_begin,
  1276. priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN));
  1277. writel_relaxed(vmode->encp.vso_end,
  1278. priv->io_base + _REG(ENCP_VIDEO_VSO_END));
  1279. writel_relaxed(vmode->encp.vso_bline,
  1280. priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE));
  1281. if (vmode->encp.vso_eline_present)
  1282. writel_relaxed(vmode->encp.vso_eline,
  1283. priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE));
  1284. if (vmode->encp.sy_val_present)
  1285. writel_relaxed(vmode->encp.sy_val,
  1286. priv->io_base + _REG(ENCP_VIDEO_SY_VAL));
  1287. if (vmode->encp.sy2_val_present)
  1288. writel_relaxed(vmode->encp.sy2_val,
  1289. priv->io_base + _REG(ENCP_VIDEO_SY2_VAL));
  1290. writel_relaxed(vmode->encp.max_lncnt,
  1291. priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT));
  1292. writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
  1293. /* Set DE signal’s polarity is active high */
  1294. writel_bits_relaxed(ENCP_VIDEO_MODE_DE_V_HIGH,
  1295. ENCP_VIDEO_MODE_DE_V_HIGH,
  1296. priv->io_base + _REG(ENCP_VIDEO_MODE));
  1297. /* Program DE timing */
  1298. de_h_begin = modulo(readl_relaxed(priv->io_base +
  1299. _REG(ENCP_VIDEO_HAVON_BEGIN))
  1300. + venc_hdmi_latency,
  1301. total_pixels_venc);
  1302. de_h_end = modulo(de_h_begin + active_pixels_venc,
  1303. total_pixels_venc);
  1304. writel_relaxed(de_h_begin,
  1305. priv->io_base + _REG(ENCP_DE_H_BEGIN));
  1306. writel_relaxed(de_h_end,
  1307. priv->io_base + _REG(ENCP_DE_H_END));
  1308. /* Program DE timing for even field */
  1309. de_v_begin_even = readl_relaxed(priv->io_base
  1310. + _REG(ENCP_VIDEO_VAVON_BLINE));
  1311. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  1312. de_v_end_even = de_v_begin_even +
  1313. (mode->vdisplay / 2);
  1314. else
  1315. de_v_end_even = de_v_begin_even + mode->vdisplay;
  1316. writel_relaxed(de_v_begin_even,
  1317. priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN));
  1318. writel_relaxed(de_v_end_even,
  1319. priv->io_base + _REG(ENCP_DE_V_END_EVEN));
  1320. /* Program DE timing for odd field if needed */
  1321. if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
  1322. unsigned int ofld_voav_ofst =
  1323. readl_relaxed(priv->io_base +
  1324. _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
  1325. de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4)
  1326. + de_v_begin_even
  1327. + ((mode->vtotal - 1) / 2);
  1328. de_v_end_odd = de_v_begin_odd + (mode->vdisplay / 2);
  1329. writel_relaxed(de_v_begin_odd,
  1330. priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD));
  1331. writel_relaxed(de_v_end_odd,
  1332. priv->io_base + _REG(ENCP_DE_V_END_ODD));
  1333. }
  1334. /* Program Hsync timing */
  1335. if ((de_h_end + front_porch_venc) >= total_pixels_venc) {
  1336. hs_begin = de_h_end
  1337. + front_porch_venc
  1338. - total_pixels_venc;
  1339. vs_adjust = 1;
  1340. } else {
  1341. hs_begin = de_h_end
  1342. + front_porch_venc;
  1343. vs_adjust = 0;
  1344. }
  1345. hs_end = modulo(hs_begin + hsync_pixels_venc,
  1346. total_pixels_venc);
  1347. writel_relaxed(hs_begin,
  1348. priv->io_base + _REG(ENCP_DVI_HSO_BEGIN));
  1349. writel_relaxed(hs_end,
  1350. priv->io_base + _REG(ENCP_DVI_HSO_END));
  1351. /* Program Vsync timing for even field */
  1352. if (de_v_begin_even >=
  1353. (sof_lines + vsync_lines + (1 - vs_adjust)))
  1354. vs_bline_evn = de_v_begin_even
  1355. - sof_lines
  1356. - vsync_lines
  1357. - (1 - vs_adjust);
  1358. else
  1359. vs_bline_evn = mode->vtotal
  1360. + de_v_begin_even
  1361. - sof_lines
  1362. - vsync_lines
  1363. - (1 - vs_adjust);
  1364. vs_eline_evn = modulo(vs_bline_evn + vsync_lines,
  1365. mode->vtotal);
  1366. writel_relaxed(vs_bline_evn,
  1367. priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN));
  1368. writel_relaxed(vs_eline_evn,
  1369. priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN));
  1370. vso_begin_evn = hs_begin;
  1371. writel_relaxed(vso_begin_evn,
  1372. priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN));
  1373. writel_relaxed(vso_begin_evn,
  1374. priv->io_base + _REG(ENCP_DVI_VSO_END_EVN));
  1375. /* Program Vsync timing for odd field if needed */
  1376. if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
  1377. vs_bline_odd = (de_v_begin_odd - 1)
  1378. - sof_lines
  1379. - vsync_lines;
  1380. vs_eline_odd = (de_v_begin_odd - 1)
  1381. - vsync_lines;
  1382. vso_begin_odd = modulo(hs_begin
  1383. + (total_pixels_venc >> 1),
  1384. total_pixels_venc);
  1385. writel_relaxed(vs_bline_odd,
  1386. priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD));
  1387. writel_relaxed(vs_eline_odd,
  1388. priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD));
  1389. writel_relaxed(vso_begin_odd,
  1390. priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD));
  1391. writel_relaxed(vso_begin_odd,
  1392. priv->io_base + _REG(ENCP_DVI_VSO_END_ODD));
  1393. }
  1394. /* Select ENCP for VIU */
  1395. meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP);
  1396. }
  1397. /* Set VPU HDMI setting */
  1398. /* Select ENCP or ENCI data to HDMI */
  1399. if (use_enci)
  1400. reg = VPU_HDMI_ENCI_DATA_TO_HDMI;
  1401. else
  1402. reg = VPU_HDMI_ENCP_DATA_TO_HDMI;
  1403. /* Invert polarity of HSYNC from VENC */
  1404. if (mode->flags & DRM_MODE_FLAG_PHSYNC)
  1405. reg |= VPU_HDMI_INV_HSYNC;
  1406. /* Invert polarity of VSYNC from VENC */
  1407. if (mode->flags & DRM_MODE_FLAG_PVSYNC)
  1408. reg |= VPU_HDMI_INV_VSYNC;
  1409. /* Output data format */
  1410. reg |= ycrcb_map;
  1411. /*
  1412. * Write rate to the async FIFO between VENC and HDMI.
  1413. * One write every 2 wr_clk.
  1414. */
  1415. if (venc_repeat || yuv420_mode)
  1416. reg |= VPU_HDMI_WR_RATE(2);
  1417. /*
  1418. * Read rate to the async FIFO between VENC and HDMI.
  1419. * One read every 2 wr_clk.
  1420. */
  1421. if (hdmi_repeat)
  1422. reg |= VPU_HDMI_RD_RATE(2);
  1423. writel_relaxed(reg, priv->io_base + _REG(VPU_HDMI_SETTING));
  1424. priv->venc.hdmi_repeat = hdmi_repeat;
  1425. priv->venc.venc_repeat = venc_repeat;
  1426. priv->venc.hdmi_use_enci = use_enci;
  1427. priv->venc.current_mode = MESON_VENC_MODE_HDMI;
  1428. }
  1429. EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
  1430. void meson_venci_cvbs_mode_set(struct meson_drm *priv,
  1431. struct meson_cvbs_enci_mode *mode)
  1432. {
  1433. u32 reg;
  1434. if (mode->mode_tag == priv->venc.current_mode)
  1435. return;
  1436. /* CVBS Filter settings */
  1437. writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
  1438. priv->io_base + _REG(ENCI_CFILT_CTRL));
  1439. writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
  1440. ENCI_CFILT_CMPT_CB_DLY(1),
  1441. priv->io_base + _REG(ENCI_CFILT_CTRL2));
  1442. /* Digital Video Select : Interlace, clk27 clk, external */
  1443. writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
  1444. /* Reset Video Mode */
  1445. writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
  1446. writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
  1447. /* Horizontal sync signal output */
  1448. writel_relaxed(mode->hso_begin,
  1449. priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
  1450. writel_relaxed(mode->hso_end,
  1451. priv->io_base + _REG(ENCI_SYNC_HSO_END));
  1452. /* Vertical Sync lines */
  1453. writel_relaxed(mode->vso_even,
  1454. priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
  1455. writel_relaxed(mode->vso_odd,
  1456. priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
  1457. /* Macrovision max amplitude change */
  1458. writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
  1459. ENCI_MACV_MAX_AMP_VAL(mode->macv_max_amp),
  1460. priv->io_base + _REG(ENCI_MACV_MAX_AMP));
  1461. /* Video mode */
  1462. writel_relaxed(mode->video_prog_mode,
  1463. priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
  1464. writel_relaxed(mode->video_mode,
  1465. priv->io_base + _REG(ENCI_VIDEO_MODE));
  1466. /*
  1467. * Advanced Video Mode :
  1468. * Demux shifting 0x2
  1469. * Blank line end at line17/22
  1470. * High bandwidth Luma Filter
  1471. * Low bandwidth Chroma Filter
  1472. * Bypass luma low pass filter
  1473. * No macrovision on CSYNC
  1474. */
  1475. writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
  1476. ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
  1477. ENCI_VIDEO_MODE_ADV_YBW_HIGH,
  1478. priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
  1479. writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
  1480. /* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
  1481. writel_relaxed(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));
  1482. /* 0x3 Y, C, and Component Y delay */
  1483. writel_relaxed(mode->yc_delay, priv->io_base + _REG(ENCI_YC_DELAY));
  1484. /* Timings */
  1485. writel_relaxed(mode->pixel_start,
  1486. priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
  1487. writel_relaxed(mode->pixel_end,
  1488. priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));
  1489. writel_relaxed(mode->top_field_line_start,
  1490. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
  1491. writel_relaxed(mode->top_field_line_end,
  1492. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));
  1493. writel_relaxed(mode->bottom_field_line_start,
  1494. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
  1495. writel_relaxed(mode->bottom_field_line_end,
  1496. priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));
  1497. /* Internal Venc, Internal VIU Sync, Internal Vencoder */
  1498. writel_relaxed(0, priv->io_base + _REG(VENC_SYNC_ROUTE));
  1499. /* UNreset Interlaced TV Encoder */
  1500. writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
  1501. /*
  1502. * Enable Vfifo2vd and set Y_Cb_Y_Cr:
  1503. * Corresponding value:
  1504. * Y => 00 or 10
  1505. * Cb => 01
  1506. * Cr => 11
  1507. * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
  1508. */
  1509. writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
  1510. ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
  1511. priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
  1512. /* Power UP Dacs */
  1513. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
  1514. /* Video Upsampling */
  1515. /*
  1516. * CTRL0, CTRL1 and CTRL2:
  1517. * Filter0: input data sample every 2 cloks
  1518. * Filter1: filtering and upsample enable
  1519. */
  1520. reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN |
  1521. VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN;
  1522. /*
  1523. * Upsample CTRL0:
  1524. * Interlace High Bandwidth Luma
  1525. */
  1526. writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg,
  1527. priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
  1528. /*
  1529. * Upsample CTRL1:
  1530. * Interlace Pb
  1531. */
  1532. writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg,
  1533. priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
  1534. /*
  1535. * Upsample CTRL2:
  1536. * Interlace R
  1537. */
  1538. writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg,
  1539. priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
  1540. /* Select Interlace Y DACs */
  1541. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
  1542. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL1));
  1543. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL2));
  1544. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL3));
  1545. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL4));
  1546. writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL5));
  1547. /* Select ENCI for VIU */
  1548. meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
  1549. /* Enable ENCI FIFO */
  1550. writel_relaxed(VENC_VDAC_FIFO_EN_ENCI_ENABLE,
  1551. priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
  1552. /* Select ENCI DACs 0, 1, 4, and 5 */
  1553. writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
  1554. writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
  1555. /* Interlace video enable */
  1556. writel_relaxed(ENCI_VIDEO_EN_ENABLE,
  1557. priv->io_base + _REG(ENCI_VIDEO_EN));
  1558. /* Configure Video Saturation / Contrast / Brightness / Hue */
  1559. writel_relaxed(mode->video_saturation,
  1560. priv->io_base + _REG(ENCI_VIDEO_SAT));
  1561. writel_relaxed(mode->video_contrast,
  1562. priv->io_base + _REG(ENCI_VIDEO_CONT));
  1563. writel_relaxed(mode->video_brightness,
  1564. priv->io_base + _REG(ENCI_VIDEO_BRIGHT));
  1565. writel_relaxed(mode->video_hue,
  1566. priv->io_base + _REG(ENCI_VIDEO_HUE));
  1567. /* Enable DAC0 Filter */
  1568. writel_relaxed(VENC_VDAC_DAC0_FILT_CTRL0_EN,
  1569. priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
  1570. writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
  1571. /* 0 in Macrovision register 0 */
  1572. writel_relaxed(0, priv->io_base + _REG(ENCI_MACV_N0));
  1573. /* Analog Synchronization and color burst value adjust */
  1574. writel_relaxed(mode->analog_sync_adj,
  1575. priv->io_base + _REG(ENCI_SYNC_ADJ));
  1576. priv->venc.current_mode = mode->mode_tag;
  1577. }
  1578. /* Returns the current ENCI field polarity */
  1579. unsigned int meson_venci_get_field(struct meson_drm *priv)
  1580. {
  1581. return readl_relaxed(priv->io_base + _REG(ENCI_INFO_READ)) & BIT(29);
  1582. }
  1583. void meson_venc_enable_vsync(struct meson_drm *priv)
  1584. {
  1585. writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
  1586. priv->io_base + _REG(VENC_INTCTRL));
  1587. regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
  1588. }
  1589. void meson_venc_disable_vsync(struct meson_drm *priv)
  1590. {
  1591. regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
  1592. writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
  1593. }
  1594. void meson_venc_init(struct meson_drm *priv)
  1595. {
  1596. /* Disable CVBS VDAC */
  1597. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
  1598. regmap_write(priv->hhi, HHI_VDAC_CNTL0_G12A, 0);
  1599. regmap_write(priv->hhi, HHI_VDAC_CNTL1_G12A, 8);
  1600. } else {
  1601. regmap_write(priv->hhi, HHI_VDAC_CNTL0, 0);
  1602. regmap_write(priv->hhi, HHI_VDAC_CNTL1, 8);
  1603. }
  1604. /* Power Down Dacs */
  1605. writel_relaxed(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
  1606. /* Disable HDMI PHY */
  1607. regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
  1608. /* Disable HDMI */
  1609. writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI |
  1610. VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
  1611. priv->io_base + _REG(VPU_HDMI_SETTING));
  1612. /* Disable all encoders */
  1613. writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
  1614. writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
  1615. writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
  1616. /* Disable VSync IRQ */
  1617. meson_venc_disable_vsync(priv);
  1618. priv->venc.current_mode = MESON_VENC_MODE_NONE;
  1619. }