meson_vclk.c 32 KB

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