meson_vclk.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Amlogic Meson Video Processing Unit driver
  4. *
  5. * Copyright (c) 2018 BayLibre, SAS.
  6. * Author: Neil Armstrong <narmstrong@baylibre.com>
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <edid.h>
  11. #include <linux/bitops.h>
  12. #include "meson_vpu.h"
  13. #include <log.h>
  14. #include <linux/iopoll.h>
  15. #include <linux/math64.h>
  16. #define writel_bits(mask, val, addr) \
  17. writel((readl(addr) & ~(mask)) | (val), addr)
  18. enum {
  19. MESON_VCLK_TARGET_CVBS = 0,
  20. MESON_VCLK_TARGET_HDMI = 1,
  21. MESON_VCLK_TARGET_DMT = 2,
  22. };
  23. /* HHI Registers */
  24. #define HHI_VID_PLL_CLK_DIV 0x1a0 /* 0x68 offset in data sheet */
  25. #define VID_PLL_EN BIT(19)
  26. #define VID_PLL_BYPASS BIT(18)
  27. #define VID_PLL_PRESET BIT(15)
  28. #define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
  29. #define VCLK2_DIV_MASK 0xff
  30. #define VCLK2_DIV_EN BIT(16)
  31. #define VCLK2_DIV_RESET BIT(17)
  32. #define CTS_VDAC_SEL_MASK (0xf << 28)
  33. #define CTS_VDAC_SEL_SHIFT 28
  34. #define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
  35. #define VCLK2_EN BIT(19)
  36. #define VCLK2_SEL_MASK (0x7 << 16)
  37. #define VCLK2_SEL_SHIFT 16
  38. #define VCLK2_SOFT_RESET BIT(15)
  39. #define VCLK2_DIV1_EN BIT(0)
  40. #define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */
  41. #define VCLK_DIV_MASK 0xff
  42. #define VCLK_DIV_EN BIT(16)
  43. #define VCLK_DIV_RESET BIT(17)
  44. #define CTS_ENCP_SEL_MASK (0xf << 24)
  45. #define CTS_ENCP_SEL_SHIFT 24
  46. #define CTS_ENCI_SEL_MASK (0xf << 28)
  47. #define CTS_ENCI_SEL_SHIFT 28
  48. #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
  49. #define VCLK_EN BIT(19)
  50. #define VCLK_SEL_MASK (0x7 << 16)
  51. #define VCLK_SEL_SHIFT 16
  52. #define VCLK_SOFT_RESET BIT(15)
  53. #define VCLK_DIV1_EN BIT(0)
  54. #define VCLK_DIV2_EN BIT(1)
  55. #define VCLK_DIV4_EN BIT(2)
  56. #define VCLK_DIV6_EN BIT(3)
  57. #define VCLK_DIV12_EN BIT(4)
  58. #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
  59. #define CTS_ENCI_EN BIT(0)
  60. #define CTS_ENCP_EN BIT(2)
  61. #define CTS_VDAC_EN BIT(4)
  62. #define HDMI_TX_PIXEL_EN BIT(5)
  63. #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
  64. #define HDMI_TX_PIXEL_SEL_MASK (0xf << 16)
  65. #define HDMI_TX_PIXEL_SEL_SHIFT 16
  66. #define CTS_HDMI_SYS_SEL_MASK (0x7 << 9)
  67. #define CTS_HDMI_SYS_DIV_MASK (0x7f)
  68. #define CTS_HDMI_SYS_EN BIT(8)
  69. #define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
  70. #define HHI_HDMI_PLL_CNTL_EN BIT(30)
  71. #define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
  72. #define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
  73. #define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */
  74. #define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */
  75. #define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */
  76. #define HHI_HDMI_PLL_CNTL7 0x338 /* 0xce offset in data sheet */
  77. #define HDMI_PLL_RESET BIT(28)
  78. #define HDMI_PLL_RESET_G12A BIT(29)
  79. #define HDMI_PLL_LOCK BIT(31)
  80. #define HDMI_PLL_LOCK_G12A (3 << 30)
  81. #define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001)
  82. /* VID PLL Dividers */
  83. enum {
  84. VID_PLL_DIV_1 = 0,
  85. VID_PLL_DIV_2,
  86. VID_PLL_DIV_2p5,
  87. VID_PLL_DIV_3,
  88. VID_PLL_DIV_3p5,
  89. VID_PLL_DIV_3p75,
  90. VID_PLL_DIV_4,
  91. VID_PLL_DIV_5,
  92. VID_PLL_DIV_6,
  93. VID_PLL_DIV_6p25,
  94. VID_PLL_DIV_7,
  95. VID_PLL_DIV_7p5,
  96. VID_PLL_DIV_12,
  97. VID_PLL_DIV_14,
  98. VID_PLL_DIV_15,
  99. };
  100. void meson_vid_pll_set(struct meson_vpu_priv *priv, unsigned int div)
  101. {
  102. unsigned int shift_val = 0;
  103. unsigned int shift_sel = 0;
  104. /* Disable vid_pll output clock */
  105. hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
  106. hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
  107. switch (div) {
  108. case VID_PLL_DIV_2:
  109. shift_val = 0x0aaa;
  110. shift_sel = 0;
  111. break;
  112. case VID_PLL_DIV_2p5:
  113. shift_val = 0x5294;
  114. shift_sel = 2;
  115. break;
  116. case VID_PLL_DIV_3:
  117. shift_val = 0x0db6;
  118. shift_sel = 0;
  119. break;
  120. case VID_PLL_DIV_3p5:
  121. shift_val = 0x36cc;
  122. shift_sel = 1;
  123. break;
  124. case VID_PLL_DIV_3p75:
  125. shift_val = 0x6666;
  126. shift_sel = 2;
  127. break;
  128. case VID_PLL_DIV_4:
  129. shift_val = 0x0ccc;
  130. shift_sel = 0;
  131. break;
  132. case VID_PLL_DIV_5:
  133. shift_val = 0x739c;
  134. shift_sel = 2;
  135. break;
  136. case VID_PLL_DIV_6:
  137. shift_val = 0x0e38;
  138. shift_sel = 0;
  139. break;
  140. case VID_PLL_DIV_6p25:
  141. shift_val = 0x0000;
  142. shift_sel = 3;
  143. break;
  144. case VID_PLL_DIV_7:
  145. shift_val = 0x3c78;
  146. shift_sel = 1;
  147. break;
  148. case VID_PLL_DIV_7p5:
  149. shift_val = 0x78f0;
  150. shift_sel = 2;
  151. break;
  152. case VID_PLL_DIV_12:
  153. shift_val = 0x0fc0;
  154. shift_sel = 0;
  155. break;
  156. case VID_PLL_DIV_14:
  157. shift_val = 0x3f80;
  158. shift_sel = 1;
  159. break;
  160. case VID_PLL_DIV_15:
  161. shift_val = 0x7f80;
  162. shift_sel = 2;
  163. break;
  164. }
  165. if (div == VID_PLL_DIV_1) {
  166. /* Enable vid_pll bypass to HDMI pll */
  167. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  168. VID_PLL_BYPASS, VID_PLL_BYPASS);
  169. } else {
  170. /* Disable Bypass */
  171. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  172. VID_PLL_BYPASS, 0);
  173. /* Clear sel */
  174. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  175. 3 << 16, 0);
  176. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  177. VID_PLL_PRESET, 0);
  178. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  179. 0x7fff, 0);
  180. /* Setup sel and val */
  181. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  182. 3 << 16, shift_sel << 16);
  183. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  184. VID_PLL_PRESET, VID_PLL_PRESET);
  185. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  186. 0x7fff, shift_val);
  187. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  188. VID_PLL_PRESET, 0);
  189. }
  190. /* Enable the vid_pll output clock */
  191. hhi_update_bits(HHI_VID_PLL_CLK_DIV,
  192. VID_PLL_EN, VID_PLL_EN);
  193. }
  194. /*
  195. * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
  196. *
  197. * TOFIX: Refactor into table to also handle HDMI frequency and paths
  198. */
  199. static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv)
  200. {
  201. unsigned int val;
  202. /* Setup PLL to output 1.485GHz */
  203. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
  204. hhi_write(HHI_HDMI_PLL_CNTL, 0x5800023d);
  205. hhi_write(HHI_HDMI_PLL_CNTL2, 0x00404e00);
  206. hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  207. hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
  208. hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
  209. hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
  210. hhi_write(HHI_HDMI_PLL_CNTL, 0x4800023d);
  211. /* Poll for lock bit */
  212. readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
  213. (val & HDMI_PLL_LOCK), 10);
  214. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  215. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
  216. hhi_write(HHI_HDMI_PLL_CNTL, 0x4000027b);
  217. hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb300);
  218. hhi_write(HHI_HDMI_PLL_CNTL3, 0xa6212844);
  219. hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
  220. hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
  221. hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
  222. /* Reset PLL */
  223. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  224. HDMI_PLL_RESET, HDMI_PLL_RESET);
  225. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  226. HDMI_PLL_RESET, 0);
  227. /* Poll for lock bit */
  228. readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
  229. (val & HDMI_PLL_LOCK), 10);
  230. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
  231. hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7);
  232. hhi_write(HHI_HDMI_PLL_CNTL2, 0x00010000);
  233. hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000);
  234. hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a28dc00);
  235. hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290);
  236. hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000);
  237. hhi_write(HHI_HDMI_PLL_CNTL7, 0x56540000);
  238. hhi_write(HHI_HDMI_PLL_CNTL, 0x3a0504f7);
  239. hhi_write(HHI_HDMI_PLL_CNTL, 0x1a0504f7);
  240. /* Poll for lock bit */
  241. readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
  242. ((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A),
  243. 10);
  244. }
  245. /* Disable VCLK2 */
  246. hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
  247. /* Setup vid_pll to /1 */
  248. meson_vid_pll_set(priv, VID_PLL_DIV_1);
  249. /* Setup the VCLK2 divider value to achieve 27MHz */
  250. hhi_update_bits(HHI_VIID_CLK_DIV,
  251. VCLK2_DIV_MASK, (55 - 1));
  252. /* select vid_pll for vclk2 */
  253. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
  254. hhi_update_bits(HHI_VIID_CLK_CNTL,
  255. VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
  256. else
  257. hhi_update_bits(HHI_VIID_CLK_CNTL,
  258. VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
  259. /* enable vclk2 gate */
  260. hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
  261. /* select vclk_div1 for enci */
  262. hhi_update_bits(HHI_VID_CLK_DIV,
  263. CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
  264. /* select vclk_div1 for vdac */
  265. hhi_update_bits(HHI_VIID_CLK_DIV,
  266. CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
  267. /* release vclk2_div_reset and enable vclk2_div */
  268. hhi_update_bits(HHI_VIID_CLK_DIV,
  269. VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
  270. /* enable vclk2_div1 gate */
  271. hhi_update_bits(HHI_VIID_CLK_CNTL,
  272. VCLK2_DIV1_EN, VCLK2_DIV1_EN);
  273. /* reset vclk2 */
  274. hhi_update_bits(HHI_VIID_CLK_CNTL,
  275. VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
  276. hhi_update_bits(HHI_VIID_CLK_CNTL,
  277. VCLK2_SOFT_RESET, 0);
  278. /* enable enci_clk */
  279. hhi_update_bits(HHI_VID_CLK_CNTL2,
  280. CTS_ENCI_EN, CTS_ENCI_EN);
  281. /* enable vdac_clk */
  282. hhi_update_bits(HHI_VID_CLK_CNTL2,
  283. CTS_VDAC_EN, CTS_VDAC_EN);
  284. }
  285. enum {
  286. /* PLL O1 O2 O3 VP DV EN TX */
  287. /* 4320 /4 /4 /1 /5 /1 => /2 /2 */
  288. MESON_VCLK_HDMI_ENCI_54000 = 0,
  289. /* 4320 /4 /4 /1 /5 /1 => /1 /2 */
  290. MESON_VCLK_HDMI_DDR_54000,
  291. /* 2970 /4 /1 /1 /5 /1 => /1 /2 */
  292. MESON_VCLK_HDMI_DDR_148500,
  293. /* 2970 /2 /2 /2 /5 /1 => /1 /1 */
  294. MESON_VCLK_HDMI_74250,
  295. /* 2970 /1 /2 /2 /5 /1 => /1 /1 */
  296. MESON_VCLK_HDMI_148500,
  297. /* 2970 /1 /1 /1 /5 /2 => /1 /1 */
  298. MESON_VCLK_HDMI_297000,
  299. /* 5940 /1 /1 /2 /5 /1 => /1 /1 */
  300. MESON_VCLK_HDMI_594000
  301. };
  302. struct meson_vclk_params {
  303. unsigned int pixel_freq;
  304. unsigned int pll_base_freq;
  305. unsigned int pll_od1;
  306. unsigned int pll_od2;
  307. unsigned int pll_od3;
  308. unsigned int vid_pll_div;
  309. unsigned int vclk_div;
  310. } params[] = {
  311. [MESON_VCLK_HDMI_ENCI_54000] = {
  312. .pixel_freq = 54000,
  313. .pll_base_freq = 4320000,
  314. .pll_od1 = 4,
  315. .pll_od2 = 4,
  316. .pll_od3 = 1,
  317. .vid_pll_div = VID_PLL_DIV_5,
  318. .vclk_div = 1,
  319. },
  320. [MESON_VCLK_HDMI_DDR_54000] = {
  321. .pixel_freq = 54000,
  322. .pll_base_freq = 4320000,
  323. .pll_od1 = 4,
  324. .pll_od2 = 4,
  325. .pll_od3 = 1,
  326. .vid_pll_div = VID_PLL_DIV_5,
  327. .vclk_div = 1,
  328. },
  329. [MESON_VCLK_HDMI_DDR_148500] = {
  330. .pixel_freq = 148500,
  331. .pll_base_freq = 2970000,
  332. .pll_od1 = 4,
  333. .pll_od2 = 1,
  334. .pll_od3 = 1,
  335. .vid_pll_div = VID_PLL_DIV_5,
  336. .vclk_div = 1,
  337. },
  338. [MESON_VCLK_HDMI_74250] = {
  339. .pixel_freq = 74250,
  340. .pll_base_freq = 2970000,
  341. .pll_od1 = 2,
  342. .pll_od2 = 2,
  343. .pll_od3 = 2,
  344. .vid_pll_div = VID_PLL_DIV_5,
  345. .vclk_div = 1,
  346. },
  347. [MESON_VCLK_HDMI_148500] = {
  348. .pixel_freq = 148500,
  349. .pll_base_freq = 2970000,
  350. .pll_od1 = 1,
  351. .pll_od2 = 2,
  352. .pll_od3 = 2,
  353. .vid_pll_div = VID_PLL_DIV_5,
  354. .vclk_div = 1,
  355. },
  356. [MESON_VCLK_HDMI_297000] = {
  357. .pixel_freq = 297000,
  358. .pll_base_freq = 5940000,
  359. .pll_od1 = 2,
  360. .pll_od2 = 1,
  361. .pll_od3 = 1,
  362. .vid_pll_div = VID_PLL_DIV_5,
  363. .vclk_div = 2,
  364. },
  365. [MESON_VCLK_HDMI_594000] = {
  366. .pixel_freq = 594000,
  367. .pll_base_freq = 5940000,
  368. .pll_od1 = 1,
  369. .pll_od2 = 1,
  370. .pll_od3 = 2,
  371. .vid_pll_div = VID_PLL_DIV_5,
  372. .vclk_div = 1,
  373. },
  374. { /* sentinel */ },
  375. };
  376. static inline unsigned int pll_od_to_reg(unsigned int od)
  377. {
  378. switch (od) {
  379. case 1:
  380. return 0;
  381. case 2:
  382. return 1;
  383. case 4:
  384. return 2;
  385. case 8:
  386. return 3;
  387. }
  388. /* Invalid */
  389. return 0;
  390. }
  391. void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m,
  392. unsigned int frac, unsigned int od1,
  393. unsigned int od2, unsigned int od3)
  394. {
  395. unsigned int val;
  396. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
  397. hhi_write(HHI_HDMI_PLL_CNTL, 0x58000200 | m);
  398. if (frac)
  399. hhi_write(HHI_HDMI_PLL_CNTL2,
  400. 0x00004000 | frac);
  401. else
  402. hhi_write(HHI_HDMI_PLL_CNTL2,
  403. 0x00000000);
  404. hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  405. hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
  406. hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
  407. hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
  408. /* Enable and unreset */
  409. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  410. 0x7 << 28, 0x4 << 28);
  411. /* Poll for lock bit */
  412. readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
  413. (val & HDMI_PLL_LOCK), 10);
  414. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  415. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
  416. hhi_write(HHI_HDMI_PLL_CNTL, 0x40000200 | m);
  417. hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
  418. hhi_write(HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  419. hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  420. hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
  421. hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
  422. /* Reset PLL */
  423. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  424. HDMI_PLL_RESET, HDMI_PLL_RESET);
  425. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  426. HDMI_PLL_RESET, 0);
  427. /* Poll for lock bit */
  428. readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
  429. (val & HDMI_PLL_LOCK), 10);
  430. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
  431. hhi_write(HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m);
  432. /* Enable and reset */
  433. hhi_update_bits(HHI_HDMI_PLL_CNTL, 0x3 << 28, 0x3 << 28);
  434. hhi_write(HHI_HDMI_PLL_CNTL2, frac);
  435. hhi_write(HHI_HDMI_PLL_CNTL3, 0x00000000);
  436. /* G12A HDMI PLL Needs specific parameters for 5.4GHz */
  437. if (m >= 0xf7) {
  438. if (frac < 0x10000) {
  439. hhi_write(HHI_HDMI_PLL_CNTL4, 0x6a685c00);
  440. hhi_write(HHI_HDMI_PLL_CNTL5, 0x11551293);
  441. } else {
  442. hhi_write(HHI_HDMI_PLL_CNTL4, 0xea68dc00);
  443. hhi_write(HHI_HDMI_PLL_CNTL5, 0x65771290);
  444. }
  445. hhi_write(HHI_HDMI_PLL_CNTL6, 0x39272000);
  446. hhi_write(HHI_HDMI_PLL_CNTL7, 0x55540000);
  447. } else {
  448. hhi_write(HHI_HDMI_PLL_CNTL4, 0x0a691c00);
  449. hhi_write(HHI_HDMI_PLL_CNTL5, 0x33771290);
  450. hhi_write(HHI_HDMI_PLL_CNTL6, 0x39270000);
  451. hhi_write(HHI_HDMI_PLL_CNTL7, 0x50540000);
  452. }
  453. do {
  454. /* Reset PLL */
  455. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  456. HDMI_PLL_RESET_G12A,
  457. HDMI_PLL_RESET_G12A);
  458. /* UN-Reset PLL */
  459. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  460. HDMI_PLL_RESET_G12A, 0);
  461. /* Poll for lock bits */
  462. if (!readl_poll_timeout(
  463. priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
  464. ((val & HDMI_PLL_LOCK_G12A)
  465. == HDMI_PLL_LOCK_G12A), 100))
  466. break;
  467. } while (1);
  468. }
  469. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
  470. hhi_update_bits(HHI_HDMI_PLL_CNTL2,
  471. 3 << 16, pll_od_to_reg(od1) << 16);
  472. else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  473. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
  474. hhi_update_bits(HHI_HDMI_PLL_CNTL3,
  475. 3 << 21, pll_od_to_reg(od1) << 21);
  476. else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
  477. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  478. 3 << 16, pll_od_to_reg(od1) << 16);
  479. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
  480. hhi_update_bits(HHI_HDMI_PLL_CNTL2,
  481. 3 << 22, pll_od_to_reg(od2) << 22);
  482. else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  483. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
  484. hhi_update_bits(HHI_HDMI_PLL_CNTL3,
  485. 3 << 23, pll_od_to_reg(od2) << 23);
  486. else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
  487. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  488. 3 << 18, pll_od_to_reg(od2) << 18);
  489. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
  490. hhi_update_bits(HHI_HDMI_PLL_CNTL2,
  491. 3 << 18, pll_od_to_reg(od3) << 18);
  492. else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  493. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
  494. hhi_update_bits(HHI_HDMI_PLL_CNTL3,
  495. 3 << 19, pll_od_to_reg(od3) << 19);
  496. else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
  497. hhi_update_bits(HHI_HDMI_PLL_CNTL,
  498. 3 << 20, pll_od_to_reg(od3) << 20);
  499. }
  500. #define XTAL_FREQ 24000
  501. static unsigned int meson_hdmi_pll_get_m(struct meson_vpu_priv *priv,
  502. unsigned int pll_freq)
  503. {
  504. /* The GXBB PLL has a /2 pre-multiplier */
  505. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
  506. pll_freq /= 2;
  507. return pll_freq / XTAL_FREQ;
  508. }
  509. #define HDMI_FRAC_MAX_GXBB 4096
  510. #define HDMI_FRAC_MAX_GXL 1024
  511. #define HDMI_FRAC_MAX_G12A 131072
  512. static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv,
  513. unsigned int m,
  514. unsigned int pll_freq)
  515. {
  516. unsigned int parent_freq = XTAL_FREQ;
  517. unsigned int frac_max = HDMI_FRAC_MAX_GXL;
  518. unsigned int frac_m;
  519. unsigned int frac;
  520. /* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
  521. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
  522. frac_max = HDMI_FRAC_MAX_GXBB;
  523. parent_freq *= 2;
  524. }
  525. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
  526. frac_max = HDMI_FRAC_MAX_G12A;
  527. /* We can have a perfect match !*/
  528. if (pll_freq / m == parent_freq &&
  529. pll_freq % m == 0)
  530. return 0;
  531. frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
  532. frac_m = m * frac_max;
  533. if (frac_m > frac)
  534. return frac_max;
  535. frac -= frac_m;
  536. return min((u16)frac, (u16)(frac_max - 1));
  537. }
  538. static bool meson_hdmi_pll_validate_params(struct meson_vpu_priv *priv,
  539. unsigned int m,
  540. unsigned int frac)
  541. {
  542. if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
  543. /* Empiric supported min/max dividers */
  544. if (m < 53 || m > 123)
  545. return false;
  546. if (frac >= HDMI_FRAC_MAX_GXBB)
  547. return false;
  548. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  549. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
  550. /* Empiric supported min/max dividers */
  551. if (m < 106 || m > 247)
  552. return false;
  553. if (frac >= HDMI_FRAC_MAX_GXL)
  554. return false;
  555. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
  556. /* Empiric supported min/max dividers */
  557. if (m < 106 || m > 247)
  558. return false;
  559. if (frac >= HDMI_FRAC_MAX_G12A)
  560. return false;
  561. }
  562. return true;
  563. }
  564. static bool meson_hdmi_pll_find_params(struct meson_vpu_priv *priv,
  565. unsigned int freq,
  566. unsigned int *m,
  567. unsigned int *frac,
  568. unsigned int *od)
  569. {
  570. /* Cycle from /16 to /2 */
  571. for (*od = 16 ; *od > 1 ; *od >>= 1) {
  572. *m = meson_hdmi_pll_get_m(priv, freq * *od);
  573. if (!*m)
  574. continue;
  575. *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
  576. debug("PLL params for %dkHz: m=%x frac=%x od=%d\n",
  577. freq, *m, *frac, *od);
  578. if (meson_hdmi_pll_validate_params(priv, *m, *frac))
  579. return true;
  580. }
  581. return false;
  582. }
  583. /* pll_freq is the frequency after the OD dividers */
  584. bool meson_vclk_dmt_supported_freq(struct meson_vpu_priv *priv,
  585. unsigned int freq)
  586. {
  587. unsigned int od, m, frac;
  588. /* In DMT mode, path after PLL is always /10 */
  589. freq *= 10;
  590. if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
  591. return true;
  592. return false;
  593. }
  594. /* pll_freq is the frequency after the OD dividers */
  595. static void meson_hdmi_pll_generic_set(struct meson_vpu_priv *priv,
  596. unsigned int pll_freq)
  597. {
  598. unsigned int od, m, frac, od1, od2, od3;
  599. if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
  600. od3 = 1;
  601. if (od < 4) {
  602. od1 = 2;
  603. od2 = 1;
  604. } else {
  605. od2 = od / 4;
  606. od1 = od / od2;
  607. }
  608. debug("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
  609. pll_freq, m, frac, od1, od2, od3);
  610. meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
  611. return;
  612. }
  613. printf("Fatal, unable to find parameters for PLL freq %d\n",
  614. pll_freq);
  615. }
  616. static void
  617. meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq,
  618. unsigned int od1, unsigned int od2, unsigned int od3,
  619. unsigned int vid_pll_div, unsigned int vclk_div,
  620. unsigned int hdmi_tx_div, unsigned int venc_div,
  621. bool hdmi_use_enci, bool vic_alternate_clock)
  622. {
  623. unsigned int m = 0, frac = 0;
  624. /* Set HDMI-TX sys clock */
  625. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  626. CTS_HDMI_SYS_SEL_MASK, 0);
  627. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  628. CTS_HDMI_SYS_DIV_MASK, 0);
  629. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  630. CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
  631. /* Set HDMI PLL rate */
  632. if (!od1 && !od2 && !od3) {
  633. meson_hdmi_pll_generic_set(priv, pll_base_freq);
  634. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
  635. switch (pll_base_freq) {
  636. case 2970000:
  637. m = 0x3d;
  638. frac = vic_alternate_clock ? 0xd02 : 0xe00;
  639. break;
  640. case 4320000:
  641. m = vic_alternate_clock ? 0x59 : 0x5a;
  642. frac = vic_alternate_clock ? 0xe8f : 0;
  643. break;
  644. case 5940000:
  645. m = 0x7b;
  646. frac = vic_alternate_clock ? 0xa05 : 0xc00;
  647. break;
  648. }
  649. meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
  650. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
  651. meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
  652. switch (pll_base_freq) {
  653. case 2970000:
  654. m = 0x7b;
  655. frac = vic_alternate_clock ? 0x281 : 0x300;
  656. break;
  657. case 4320000:
  658. m = vic_alternate_clock ? 0xb3 : 0xb4;
  659. frac = vic_alternate_clock ? 0x347 : 0;
  660. break;
  661. case 5940000:
  662. m = 0xf7;
  663. frac = vic_alternate_clock ? 0x102 : 0x200;
  664. break;
  665. }
  666. meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
  667. } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
  668. switch (pll_base_freq) {
  669. case 2970000:
  670. m = 0x7b;
  671. frac = vic_alternate_clock ? 0x140b4 : 0x18000;
  672. break;
  673. case 4320000:
  674. m = vic_alternate_clock ? 0xb3 : 0xb4;
  675. frac = vic_alternate_clock ? 0x1a3ee : 0;
  676. break;
  677. case 5940000:
  678. m = 0xf7;
  679. frac = vic_alternate_clock ? 0x8148 : 0x10000;
  680. break;
  681. }
  682. meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
  683. }
  684. /* Setup vid_pll divider */
  685. meson_vid_pll_set(priv, vid_pll_div);
  686. /* Set VCLK div */
  687. hhi_update_bits(HHI_VID_CLK_CNTL,
  688. VCLK_SEL_MASK, 0);
  689. hhi_update_bits(HHI_VID_CLK_DIV,
  690. VCLK_DIV_MASK, vclk_div - 1);
  691. /* Set HDMI-TX source */
  692. switch (hdmi_tx_div) {
  693. case 1:
  694. /* enable vclk_div1 gate */
  695. hhi_update_bits(HHI_VID_CLK_CNTL,
  696. VCLK_DIV1_EN, VCLK_DIV1_EN);
  697. /* select vclk_div1 for HDMI-TX */
  698. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  699. HDMI_TX_PIXEL_SEL_MASK, 0);
  700. break;
  701. case 2:
  702. /* enable vclk_div2 gate */
  703. hhi_update_bits(HHI_VID_CLK_CNTL,
  704. VCLK_DIV2_EN, VCLK_DIV2_EN);
  705. /* select vclk_div2 for HDMI-TX */
  706. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  707. HDMI_TX_PIXEL_SEL_MASK,
  708. 1 << HDMI_TX_PIXEL_SEL_SHIFT);
  709. break;
  710. case 4:
  711. /* enable vclk_div4 gate */
  712. hhi_update_bits(HHI_VID_CLK_CNTL,
  713. VCLK_DIV4_EN, VCLK_DIV4_EN);
  714. /* select vclk_div4 for HDMI-TX */
  715. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  716. HDMI_TX_PIXEL_SEL_MASK,
  717. 2 << HDMI_TX_PIXEL_SEL_SHIFT);
  718. break;
  719. case 6:
  720. /* enable vclk_div6 gate */
  721. hhi_update_bits(HHI_VID_CLK_CNTL,
  722. VCLK_DIV6_EN, VCLK_DIV6_EN);
  723. /* select vclk_div6 for HDMI-TX */
  724. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  725. HDMI_TX_PIXEL_SEL_MASK,
  726. 3 << HDMI_TX_PIXEL_SEL_SHIFT);
  727. break;
  728. case 12:
  729. /* enable vclk_div12 gate */
  730. hhi_update_bits(HHI_VID_CLK_CNTL,
  731. VCLK_DIV12_EN, VCLK_DIV12_EN);
  732. /* select vclk_div12 for HDMI-TX */
  733. hhi_update_bits(HHI_HDMI_CLK_CNTL,
  734. HDMI_TX_PIXEL_SEL_MASK,
  735. 4 << HDMI_TX_PIXEL_SEL_SHIFT);
  736. break;
  737. }
  738. hhi_update_bits(HHI_VID_CLK_CNTL2,
  739. HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
  740. /* Set ENCI/ENCP Source */
  741. switch (venc_div) {
  742. case 1:
  743. /* enable vclk_div1 gate */
  744. hhi_update_bits(HHI_VID_CLK_CNTL,
  745. VCLK_DIV1_EN, VCLK_DIV1_EN);
  746. if (hdmi_use_enci)
  747. /* select vclk_div1 for enci */
  748. hhi_update_bits(HHI_VID_CLK_DIV,
  749. CTS_ENCI_SEL_MASK, 0);
  750. else
  751. /* select vclk_div1 for encp */
  752. hhi_update_bits(HHI_VID_CLK_DIV,
  753. CTS_ENCP_SEL_MASK, 0);
  754. break;
  755. case 2:
  756. /* enable vclk_div2 gate */
  757. hhi_update_bits(HHI_VID_CLK_CNTL,
  758. VCLK_DIV2_EN, VCLK_DIV2_EN);
  759. if (hdmi_use_enci)
  760. /* select vclk_div2 for enci */
  761. hhi_update_bits(HHI_VID_CLK_DIV,
  762. CTS_ENCI_SEL_MASK,
  763. 1 << CTS_ENCI_SEL_SHIFT);
  764. else
  765. /* select vclk_div2 for encp */
  766. hhi_update_bits(HHI_VID_CLK_DIV,
  767. CTS_ENCP_SEL_MASK,
  768. 1 << CTS_ENCP_SEL_SHIFT);
  769. break;
  770. case 4:
  771. /* enable vclk_div4 gate */
  772. hhi_update_bits(HHI_VID_CLK_CNTL,
  773. VCLK_DIV4_EN, VCLK_DIV4_EN);
  774. if (hdmi_use_enci)
  775. /* select vclk_div4 for enci */
  776. hhi_update_bits(HHI_VID_CLK_DIV,
  777. CTS_ENCI_SEL_MASK,
  778. 2 << CTS_ENCI_SEL_SHIFT);
  779. else
  780. /* select vclk_div4 for encp */
  781. hhi_update_bits(HHI_VID_CLK_DIV,
  782. CTS_ENCP_SEL_MASK,
  783. 2 << CTS_ENCP_SEL_SHIFT);
  784. break;
  785. case 6:
  786. /* enable vclk_div6 gate */
  787. hhi_update_bits(HHI_VID_CLK_CNTL,
  788. VCLK_DIV6_EN, VCLK_DIV6_EN);
  789. if (hdmi_use_enci)
  790. /* select vclk_div6 for enci */
  791. hhi_update_bits(HHI_VID_CLK_DIV,
  792. CTS_ENCI_SEL_MASK,
  793. 3 << CTS_ENCI_SEL_SHIFT);
  794. else
  795. /* select vclk_div6 for encp */
  796. hhi_update_bits(HHI_VID_CLK_DIV,
  797. CTS_ENCP_SEL_MASK,
  798. 3 << CTS_ENCP_SEL_SHIFT);
  799. break;
  800. case 12:
  801. /* enable vclk_div12 gate */
  802. hhi_update_bits(HHI_VID_CLK_CNTL,
  803. VCLK_DIV12_EN, VCLK_DIV12_EN);
  804. if (hdmi_use_enci)
  805. /* select vclk_div12 for enci */
  806. hhi_update_bits(HHI_VID_CLK_DIV,
  807. CTS_ENCI_SEL_MASK,
  808. 4 << CTS_ENCI_SEL_SHIFT);
  809. else
  810. /* select vclk_div12 for encp */
  811. hhi_update_bits(HHI_VID_CLK_DIV,
  812. CTS_ENCP_SEL_MASK,
  813. 4 << CTS_ENCP_SEL_SHIFT);
  814. break;
  815. }
  816. if (hdmi_use_enci)
  817. /* Enable ENCI clock gate */
  818. hhi_update_bits(HHI_VID_CLK_CNTL2,
  819. CTS_ENCI_EN, CTS_ENCI_EN);
  820. else
  821. /* Enable ENCP clock gate */
  822. hhi_update_bits(HHI_VID_CLK_CNTL2,
  823. CTS_ENCP_EN, CTS_ENCP_EN);
  824. hhi_update_bits(HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
  825. }
  826. static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target,
  827. unsigned int vclk_freq, unsigned int venc_freq,
  828. unsigned int dac_freq, bool hdmi_use_enci)
  829. {
  830. bool vic_alternate_clock = false;
  831. unsigned int freq;
  832. unsigned int hdmi_tx_div;
  833. unsigned int venc_div;
  834. if (target == MESON_VCLK_TARGET_CVBS) {
  835. meson_venci_cvbs_clock_config(priv);
  836. return;
  837. } else if (target == MESON_VCLK_TARGET_DMT) {
  838. /* The DMT clock path is fixed after the PLL:
  839. * - automatic PLL freq + OD management
  840. * - vid_pll_div = VID_PLL_DIV_5
  841. * - vclk_div = 2
  842. * - hdmi_tx_div = 1
  843. * - venc_div = 1
  844. * - encp encoder
  845. */
  846. meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
  847. VID_PLL_DIV_5, 2, 1, 1, false, false);
  848. return;
  849. }
  850. hdmi_tx_div = vclk_freq / dac_freq;
  851. if (hdmi_tx_div == 0) {
  852. printf("Fatal Error, invalid HDMI-TX freq %d\n",
  853. dac_freq);
  854. return;
  855. }
  856. venc_div = vclk_freq / venc_freq;
  857. if (venc_div == 0) {
  858. printf("Fatal Error, invalid HDMI venc freq %d\n",
  859. venc_freq);
  860. return;
  861. }
  862. for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
  863. if (vclk_freq == params[freq].pixel_freq ||
  864. vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
  865. if (vclk_freq != params[freq].pixel_freq)
  866. vic_alternate_clock = true;
  867. else
  868. vic_alternate_clock = false;
  869. if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
  870. !hdmi_use_enci)
  871. continue;
  872. if (freq == MESON_VCLK_HDMI_DDR_54000 &&
  873. hdmi_use_enci)
  874. continue;
  875. if (freq == MESON_VCLK_HDMI_DDR_148500 &&
  876. dac_freq == vclk_freq)
  877. continue;
  878. if (freq == MESON_VCLK_HDMI_148500 &&
  879. dac_freq != vclk_freq)
  880. continue;
  881. break;
  882. }
  883. }
  884. if (!params[freq].pixel_freq) {
  885. pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
  886. return;
  887. }
  888. meson_vclk_set(priv, params[freq].pll_base_freq,
  889. params[freq].pll_od1, params[freq].pll_od2,
  890. params[freq].pll_od3, params[freq].vid_pll_div,
  891. params[freq].vclk_div, hdmi_tx_div, venc_div,
  892. hdmi_use_enci, vic_alternate_clock);
  893. }
  894. void meson_vpu_setup_vclk(struct udevice *dev,
  895. const struct display_timing *mode, bool is_cvbs)
  896. {
  897. struct meson_vpu_priv *priv = dev_get_priv(dev);
  898. unsigned int vclk_freq;
  899. if (is_cvbs)
  900. return meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
  901. 0, 0, 0, false);
  902. vclk_freq = mode->pixelclock.typ / 1000;
  903. return meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT,
  904. vclk_freq, vclk_freq, vclk_freq, false);
  905. }