meson_vclk.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. /*
  2. * Copyright (C) 2016 BayLibre, SAS
  3. * Author: Neil Armstrong <narmstrong@baylibre.com>
  4. * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of the
  9. * License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <drm/drmP.h>
  22. #include "meson_drv.h"
  23. #include "meson_vclk.h"
  24. /**
  25. * DOC: Video Clocks
  26. *
  27. * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL.
  28. * We handle the following encodings :
  29. *
  30. * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks
  31. * - HDMI Pixel Clocks generation
  32. *
  33. * What is missing :
  34. *
  35. * - Genenate Pixel clocks for 2K/4K 10bit formats
  36. *
  37. * Clock generator scheme :
  38. *
  39. * .. code::
  40. *
  41. * __________ _________ _____
  42. * | | | | | |--ENCI
  43. * | HDMI PLL |-| PLL_DIV |--- VCLK--| |--ENCL
  44. * |__________| |_________| \ | MUX |--ENCP
  45. * --VCLK2-| |--VDAC
  46. * |_____|--HDMI-TX
  47. *
  48. * Final clocks can take input for either VCLK or VCLK2, but
  49. * VCLK is the preferred path for HDMI clocking and VCLK2 is the
  50. * preferred path for CVBS VDAC clocking.
  51. *
  52. * VCLK and VCLK2 have fixed divided clocks paths for /1, /2, /4, /6 or /12.
  53. *
  54. * The PLL_DIV can achieve an additional fractional dividing like
  55. * 1.5, 3.5, 3.75... to generate special 2K and 4K 10bit clocks.
  56. */
  57. /* HHI Registers */
  58. #define HHI_VID_PLL_CLK_DIV 0x1a0 /* 0x68 offset in data sheet */
  59. #define VID_PLL_EN BIT(19)
  60. #define VID_PLL_BYPASS BIT(18)
  61. #define VID_PLL_PRESET BIT(15)
  62. #define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
  63. #define VCLK2_DIV_MASK 0xff
  64. #define VCLK2_DIV_EN BIT(16)
  65. #define VCLK2_DIV_RESET BIT(17)
  66. #define CTS_VDAC_SEL_MASK (0xf << 28)
  67. #define CTS_VDAC_SEL_SHIFT 28
  68. #define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
  69. #define VCLK2_EN BIT(19)
  70. #define VCLK2_SEL_MASK (0x7 << 16)
  71. #define VCLK2_SEL_SHIFT 16
  72. #define VCLK2_SOFT_RESET BIT(15)
  73. #define VCLK2_DIV1_EN BIT(0)
  74. #define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */
  75. #define VCLK_DIV_MASK 0xff
  76. #define VCLK_DIV_EN BIT(16)
  77. #define VCLK_DIV_RESET BIT(17)
  78. #define CTS_ENCP_SEL_MASK (0xf << 24)
  79. #define CTS_ENCP_SEL_SHIFT 24
  80. #define CTS_ENCI_SEL_MASK (0xf << 28)
  81. #define CTS_ENCI_SEL_SHIFT 28
  82. #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
  83. #define VCLK_EN BIT(19)
  84. #define VCLK_SEL_MASK (0x7 << 16)
  85. #define VCLK_SEL_SHIFT 16
  86. #define VCLK_SOFT_RESET BIT(15)
  87. #define VCLK_DIV1_EN BIT(0)
  88. #define VCLK_DIV2_EN BIT(1)
  89. #define VCLK_DIV4_EN BIT(2)
  90. #define VCLK_DIV6_EN BIT(3)
  91. #define VCLK_DIV12_EN BIT(4)
  92. #define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
  93. #define CTS_ENCI_EN BIT(0)
  94. #define CTS_ENCP_EN BIT(2)
  95. #define CTS_VDAC_EN BIT(4)
  96. #define HDMI_TX_PIXEL_EN BIT(5)
  97. #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
  98. #define HDMI_TX_PIXEL_SEL_MASK (0xf << 16)
  99. #define HDMI_TX_PIXEL_SEL_SHIFT 16
  100. #define CTS_HDMI_SYS_SEL_MASK (0x7 << 9)
  101. #define CTS_HDMI_SYS_DIV_MASK (0x7f)
  102. #define CTS_HDMI_SYS_EN BIT(8)
  103. #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
  104. #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
  105. #define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
  106. #define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
  107. #define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
  108. #define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */
  109. #define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */
  110. #define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */
  111. #define HDMI_PLL_RESET BIT(28)
  112. #define HDMI_PLL_LOCK BIT(31)
  113. /* VID PLL Dividers */
  114. enum {
  115. VID_PLL_DIV_1 = 0,
  116. VID_PLL_DIV_2,
  117. VID_PLL_DIV_2p5,
  118. VID_PLL_DIV_3,
  119. VID_PLL_DIV_3p5,
  120. VID_PLL_DIV_3p75,
  121. VID_PLL_DIV_4,
  122. VID_PLL_DIV_5,
  123. VID_PLL_DIV_6,
  124. VID_PLL_DIV_6p25,
  125. VID_PLL_DIV_7,
  126. VID_PLL_DIV_7p5,
  127. VID_PLL_DIV_12,
  128. VID_PLL_DIV_14,
  129. VID_PLL_DIV_15,
  130. };
  131. void meson_vid_pll_set(struct meson_drm *priv, unsigned int div)
  132. {
  133. unsigned int shift_val = 0;
  134. unsigned int shift_sel = 0;
  135. /* Disable vid_pll output clock */
  136. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
  137. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
  138. switch (div) {
  139. case VID_PLL_DIV_2:
  140. shift_val = 0x0aaa;
  141. shift_sel = 0;
  142. break;
  143. case VID_PLL_DIV_2p5:
  144. shift_val = 0x5294;
  145. shift_sel = 2;
  146. break;
  147. case VID_PLL_DIV_3:
  148. shift_val = 0x0db6;
  149. shift_sel = 0;
  150. break;
  151. case VID_PLL_DIV_3p5:
  152. shift_val = 0x36cc;
  153. shift_sel = 1;
  154. break;
  155. case VID_PLL_DIV_3p75:
  156. shift_val = 0x6666;
  157. shift_sel = 2;
  158. break;
  159. case VID_PLL_DIV_4:
  160. shift_val = 0x0ccc;
  161. shift_sel = 0;
  162. break;
  163. case VID_PLL_DIV_5:
  164. shift_val = 0x739c;
  165. shift_sel = 2;
  166. break;
  167. case VID_PLL_DIV_6:
  168. shift_val = 0x0e38;
  169. shift_sel = 0;
  170. break;
  171. case VID_PLL_DIV_6p25:
  172. shift_val = 0x0000;
  173. shift_sel = 3;
  174. break;
  175. case VID_PLL_DIV_7:
  176. shift_val = 0x3c78;
  177. shift_sel = 1;
  178. break;
  179. case VID_PLL_DIV_7p5:
  180. shift_val = 0x78f0;
  181. shift_sel = 2;
  182. break;
  183. case VID_PLL_DIV_12:
  184. shift_val = 0x0fc0;
  185. shift_sel = 0;
  186. break;
  187. case VID_PLL_DIV_14:
  188. shift_val = 0x3f80;
  189. shift_sel = 1;
  190. break;
  191. case VID_PLL_DIV_15:
  192. shift_val = 0x7f80;
  193. shift_sel = 2;
  194. break;
  195. }
  196. if (div == VID_PLL_DIV_1)
  197. /* Enable vid_pll bypass to HDMI pll */
  198. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  199. VID_PLL_BYPASS, VID_PLL_BYPASS);
  200. else {
  201. /* Disable Bypass */
  202. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  203. VID_PLL_BYPASS, 0);
  204. /* Clear sel */
  205. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  206. 3 << 16, 0);
  207. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  208. VID_PLL_PRESET, 0);
  209. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  210. 0x7fff, 0);
  211. /* Setup sel and val */
  212. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  213. 3 << 16, shift_sel << 16);
  214. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  215. VID_PLL_PRESET, VID_PLL_PRESET);
  216. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  217. 0x7fff, shift_val);
  218. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  219. VID_PLL_PRESET, 0);
  220. }
  221. /* Enable the vid_pll output clock */
  222. regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
  223. VID_PLL_EN, VID_PLL_EN);
  224. }
  225. /*
  226. * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
  227. *
  228. * TOFIX: Refactor into table to also handle HDMI frequency and paths
  229. */
  230. static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
  231. {
  232. unsigned int val;
  233. /* Setup PLL to output 1.485GHz */
  234. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  235. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
  236. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
  237. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  238. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  239. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  240. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  241. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
  242. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  243. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
  244. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
  245. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
  246. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
  247. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
  248. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  249. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  250. /* Reset PLL */
  251. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  252. HDMI_PLL_RESET, HDMI_PLL_RESET);
  253. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  254. HDMI_PLL_RESET, 0);
  255. }
  256. /* Poll for lock bit */
  257. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
  258. (val & HDMI_PLL_LOCK), 10, 0);
  259. /* Disable VCLK2 */
  260. regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
  261. /* Setup vid_pll to /1 */
  262. meson_vid_pll_set(priv, VID_PLL_DIV_1);
  263. /* Setup the VCLK2 divider value to achieve 27MHz */
  264. regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
  265. VCLK2_DIV_MASK, (55 - 1));
  266. /* select vid_pll for vclk2 */
  267. regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
  268. VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
  269. /* enable vclk2 gate */
  270. regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
  271. /* select vclk_div1 for enci */
  272. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  273. CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
  274. /* select vclk_div1 for vdac */
  275. regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
  276. CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
  277. /* release vclk2_div_reset and enable vclk2_div */
  278. regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
  279. VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
  280. /* enable vclk2_div1 gate */
  281. regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
  282. VCLK2_DIV1_EN, VCLK2_DIV1_EN);
  283. /* reset vclk2 */
  284. regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
  285. VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
  286. regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
  287. VCLK2_SOFT_RESET, 0);
  288. /* enable enci_clk */
  289. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  290. CTS_ENCI_EN, CTS_ENCI_EN);
  291. /* enable vdac_clk */
  292. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  293. CTS_VDAC_EN, CTS_VDAC_EN);
  294. }
  295. /* PLL O1 O2 O3 VP DV EN TX */
  296. /* 4320 /4 /4 /1 /5 /1 => /2 /2 */
  297. #define MESON_VCLK_HDMI_ENCI_54000 1
  298. /* 4320 /4 /4 /1 /5 /1 => /1 /2 */
  299. #define MESON_VCLK_HDMI_DDR_54000 2
  300. /* 2970 /4 /1 /1 /5 /1 => /1 /2 */
  301. #define MESON_VCLK_HDMI_DDR_148500 3
  302. /* 4028 /4 /4 /1 /5 /2 => /1 /1 */
  303. #define MESON_VCLK_HDMI_25175 4
  304. /* 3200 /4 /2 /1 /5 /2 => /1 /1 */
  305. #define MESON_VCLK_HDMI_40000 5
  306. /* 5200 /4 /2 /1 /5 /2 => /1 /1 */
  307. #define MESON_VCLK_HDMI_65000 6
  308. /* 2970 /2 /2 /2 /5 /1 => /1 /1 */
  309. #define MESON_VCLK_HDMI_74250 7
  310. /* 4320 /4 /1 /1 /5 /2 => /1 /1 */
  311. #define MESON_VCLK_HDMI_108000 8
  312. /* 2970 /1 /2 /2 /5 /1 => /1 /1 */
  313. #define MESON_VCLK_HDMI_148500 9
  314. /* 3240 /2 /1 /1 /5 /2 => /1 /1 */
  315. #define MESON_VCLK_HDMI_162000 10
  316. /* 2970 /1 /1 /1 /5 /2 => /1 /1 */
  317. #define MESON_VCLK_HDMI_297000 11
  318. /* 5940 /1 /1 /2 /5 /1 => /1 /1 */
  319. #define MESON_VCLK_HDMI_594000 12
  320. struct meson_vclk_params {
  321. unsigned int pll_base_freq;
  322. unsigned int pll_od1;
  323. unsigned int pll_od2;
  324. unsigned int pll_od3;
  325. unsigned int vid_pll_div;
  326. unsigned int vclk_div;
  327. } params[] = {
  328. [MESON_VCLK_HDMI_ENCI_54000] = {
  329. .pll_base_freq = 4320000,
  330. .pll_od1 = 4,
  331. .pll_od2 = 4,
  332. .pll_od3 = 1,
  333. .vid_pll_div = VID_PLL_DIV_5,
  334. .vclk_div = 1,
  335. },
  336. [MESON_VCLK_HDMI_DDR_54000] = {
  337. .pll_base_freq = 4320000,
  338. .pll_od1 = 4,
  339. .pll_od2 = 4,
  340. .pll_od3 = 1,
  341. .vid_pll_div = VID_PLL_DIV_5,
  342. .vclk_div = 1,
  343. },
  344. [MESON_VCLK_HDMI_DDR_148500] = {
  345. .pll_base_freq = 2970000,
  346. .pll_od1 = 4,
  347. .pll_od2 = 1,
  348. .pll_od3 = 1,
  349. .vid_pll_div = VID_PLL_DIV_5,
  350. .vclk_div = 1,
  351. },
  352. [MESON_VCLK_HDMI_74250] = {
  353. .pll_base_freq = 2970000,
  354. .pll_od1 = 2,
  355. .pll_od2 = 2,
  356. .pll_od3 = 2,
  357. .vid_pll_div = VID_PLL_DIV_5,
  358. .vclk_div = 1,
  359. },
  360. [MESON_VCLK_HDMI_148500] = {
  361. .pll_base_freq = 2970000,
  362. .pll_od1 = 1,
  363. .pll_od2 = 2,
  364. .pll_od3 = 2,
  365. .vid_pll_div = VID_PLL_DIV_5,
  366. .vclk_div = 1,
  367. },
  368. [MESON_VCLK_HDMI_297000] = {
  369. .pll_base_freq = 2970000,
  370. .pll_od1 = 1,
  371. .pll_od2 = 1,
  372. .pll_od3 = 1,
  373. .vid_pll_div = VID_PLL_DIV_5,
  374. .vclk_div = 2,
  375. },
  376. [MESON_VCLK_HDMI_594000] = {
  377. .pll_base_freq = 5940000,
  378. .pll_od1 = 1,
  379. .pll_od2 = 1,
  380. .pll_od3 = 2,
  381. .vid_pll_div = VID_PLL_DIV_5,
  382. .vclk_div = 1,
  383. },
  384. [MESON_VCLK_HDMI_25175] = {
  385. .pll_base_freq = 4028000,
  386. .pll_od1 = 4,
  387. .pll_od2 = 4,
  388. .pll_od3 = 1,
  389. .vid_pll_div = VID_PLL_DIV_5,
  390. .vclk_div = 2,
  391. },
  392. [MESON_VCLK_HDMI_40000] = {
  393. .pll_base_freq = 3200000,
  394. .pll_od1 = 4,
  395. .pll_od2 = 2,
  396. .pll_od3 = 1,
  397. .vid_pll_div = VID_PLL_DIV_5,
  398. .vclk_div = 2,
  399. },
  400. [MESON_VCLK_HDMI_65000] = {
  401. .pll_base_freq = 5200000,
  402. .pll_od1 = 4,
  403. .pll_od2 = 2,
  404. .pll_od3 = 1,
  405. .vid_pll_div = VID_PLL_DIV_5,
  406. .vclk_div = 2,
  407. },
  408. [MESON_VCLK_HDMI_108000] = {
  409. .pll_base_freq = 4320000,
  410. .pll_od1 = 4,
  411. .pll_od2 = 1,
  412. .pll_od3 = 1,
  413. .vid_pll_div = VID_PLL_DIV_5,
  414. .vclk_div = 2,
  415. },
  416. [MESON_VCLK_HDMI_162000] = {
  417. .pll_base_freq = 3240000,
  418. .pll_od1 = 2,
  419. .pll_od2 = 1,
  420. .pll_od3 = 1,
  421. .vid_pll_div = VID_PLL_DIV_5,
  422. .vclk_div = 2,
  423. },
  424. };
  425. static inline unsigned int pll_od_to_reg(unsigned int od)
  426. {
  427. switch (od) {
  428. case 1:
  429. return 0;
  430. case 2:
  431. return 1;
  432. case 4:
  433. return 2;
  434. case 8:
  435. return 3;
  436. }
  437. /* Invalid */
  438. return 0;
  439. }
  440. void meson_hdmi_pll_set(struct meson_drm *priv,
  441. unsigned int base,
  442. unsigned int od1,
  443. unsigned int od2,
  444. unsigned int od3)
  445. {
  446. unsigned int val;
  447. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  448. switch (base) {
  449. case 2970000:
  450. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
  451. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  452. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  453. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  454. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  455. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  456. /* Enable and unreset */
  457. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  458. 0x7 << 28, 0x4 << 28);
  459. /* Poll for lock bit */
  460. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  461. val, (val & HDMI_PLL_LOCK), 10, 0);
  462. /* div_frac */
  463. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  464. 0xFFFF, 0x4e00);
  465. break;
  466. case 3200000:
  467. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000242);
  468. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  469. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  470. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  471. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  472. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  473. /* unreset */
  474. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  475. BIT(28), 0);
  476. /* Poll for lock bit */
  477. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  478. val, (val & HDMI_PLL_LOCK), 10, 0);
  479. /* div_frac */
  480. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  481. 0xFFFF, 0x4aab);
  482. break;
  483. case 3240000:
  484. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000243);
  485. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  486. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  487. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  488. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  489. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  490. /* unreset */
  491. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  492. BIT(28), 0);
  493. /* Poll for lock bit */
  494. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  495. val, (val & HDMI_PLL_LOCK), 10, 0);
  496. /* div_frac */
  497. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  498. 0xFFFF, 0x4800);
  499. break;
  500. case 3865000:
  501. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000250);
  502. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  503. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  504. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  505. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  506. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  507. /* unreset */
  508. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  509. BIT(28), 0);
  510. /* Poll for lock bit */
  511. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  512. val, (val & HDMI_PLL_LOCK), 10, 0);
  513. /* div_frac */
  514. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  515. 0xFFFF, 0x4855);
  516. break;
  517. case 4028000:
  518. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000253);
  519. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  520. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  521. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  522. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  523. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  524. /* unreset */
  525. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  526. BIT(28), 0);
  527. /* Poll for lock bit */
  528. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  529. val, (val & HDMI_PLL_LOCK), 10, 0);
  530. /* div_frac */
  531. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  532. 0xFFFF, 0x4eab);
  533. break;
  534. case 4320000:
  535. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a);
  536. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  537. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  538. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  539. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  540. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  541. /* unreset */
  542. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  543. BIT(28), 0);
  544. /* Poll for lock bit */
  545. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  546. val, (val & HDMI_PLL_LOCK), 10, 0);
  547. break;
  548. case 5940000:
  549. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b);
  550. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  551. 0xFFFF, 0x4c00);
  552. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
  553. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  554. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  555. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  556. /* unreset */
  557. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  558. BIT(28), 0);
  559. /* Poll for lock bit */
  560. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  561. val, (val & HDMI_PLL_LOCK), 10, 0);
  562. break;
  563. case 5200000:
  564. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800026c);
  565. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  566. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
  567. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  568. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  569. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  570. /* unreset */
  571. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  572. BIT(28), 0);
  573. /* Poll for lock bit */
  574. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  575. val, (val & HDMI_PLL_LOCK), 10, 0);
  576. break;
  577. };
  578. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  579. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
  580. switch (base) {
  581. case 2970000:
  582. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
  583. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
  584. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  585. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  586. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  587. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  588. break;
  589. case 3200000:
  590. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000285);
  591. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb155);
  592. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  593. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  594. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  595. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  596. break;
  597. case 3240000:
  598. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000287);
  599. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
  600. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  601. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  602. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  603. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  604. break;
  605. case 3865000:
  606. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a1);
  607. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb02b);
  608. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  609. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  610. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  611. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  612. break;
  613. case 4028000:
  614. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002a7);
  615. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb355);
  616. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  617. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  618. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  619. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  620. break;
  621. case 4320000:
  622. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4);
  623. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
  624. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  625. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  626. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  627. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  628. break;
  629. case 5940000:
  630. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002f7);
  631. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200);
  632. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  633. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  634. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  635. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  636. break;
  637. case 5200000:
  638. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002d8);
  639. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb2ab);
  640. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  641. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  642. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  643. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  644. break;
  645. };
  646. /* Reset PLL */
  647. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  648. HDMI_PLL_RESET, HDMI_PLL_RESET);
  649. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  650. HDMI_PLL_RESET, 0);
  651. /* Poll for lock bit */
  652. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
  653. (val & HDMI_PLL_LOCK), 10, 0);
  654. };
  655. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  656. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  657. 3 << 16, pll_od_to_reg(od1) << 16);
  658. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  659. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  660. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  661. 3 << 21, pll_od_to_reg(od1) << 21);
  662. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  663. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  664. 3 << 22, pll_od_to_reg(od2) << 22);
  665. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  666. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  667. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  668. 3 << 23, pll_od_to_reg(od2) << 23);
  669. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  670. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  671. 3 << 18, pll_od_to_reg(od3) << 18);
  672. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  673. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  674. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  675. 3 << 19, pll_od_to_reg(od3) << 19);
  676. }
  677. void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
  678. unsigned int vclk_freq, unsigned int venc_freq,
  679. unsigned int dac_freq, bool hdmi_use_enci)
  680. {
  681. unsigned int freq;
  682. unsigned int hdmi_tx_div;
  683. unsigned int venc_div;
  684. if (target == MESON_VCLK_TARGET_CVBS) {
  685. meson_venci_cvbs_clock_config(priv);
  686. return;
  687. }
  688. hdmi_tx_div = vclk_freq / dac_freq;
  689. if (hdmi_tx_div == 0) {
  690. pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
  691. dac_freq);
  692. return;
  693. }
  694. venc_div = vclk_freq / venc_freq;
  695. if (venc_div == 0) {
  696. pr_err("Fatal Error, invalid HDMI venc freq %d\n",
  697. venc_freq);
  698. return;
  699. }
  700. switch (vclk_freq) {
  701. case 54000:
  702. if (hdmi_use_enci)
  703. freq = MESON_VCLK_HDMI_ENCI_54000;
  704. else
  705. freq = MESON_VCLK_HDMI_DDR_54000;
  706. break;
  707. case 25175:
  708. freq = MESON_VCLK_HDMI_25175;
  709. break;
  710. case 40000:
  711. freq = MESON_VCLK_HDMI_40000;
  712. break;
  713. case 65000:
  714. freq = MESON_VCLK_HDMI_65000;
  715. break;
  716. case 74250:
  717. freq = MESON_VCLK_HDMI_74250;
  718. break;
  719. case 108000:
  720. freq = MESON_VCLK_HDMI_108000;
  721. break;
  722. case 148500:
  723. if (dac_freq != 148500)
  724. freq = MESON_VCLK_HDMI_DDR_148500;
  725. else
  726. freq = MESON_VCLK_HDMI_148500;
  727. break;
  728. case 162000:
  729. freq = MESON_VCLK_HDMI_162000;
  730. break;
  731. case 297000:
  732. freq = MESON_VCLK_HDMI_297000;
  733. break;
  734. case 594000:
  735. freq = MESON_VCLK_HDMI_594000;
  736. break;
  737. default:
  738. pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
  739. vclk_freq);
  740. return;
  741. }
  742. /* Set HDMI-TX sys clock */
  743. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  744. CTS_HDMI_SYS_SEL_MASK, 0);
  745. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  746. CTS_HDMI_SYS_DIV_MASK, 0);
  747. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  748. CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
  749. /* Set HDMI PLL rate */
  750. meson_hdmi_pll_set(priv, params[freq].pll_base_freq,
  751. params[freq].pll_od1,
  752. params[freq].pll_od2,
  753. params[freq].pll_od3);
  754. /* Setup vid_pll divider */
  755. meson_vid_pll_set(priv, params[freq].vid_pll_div);
  756. /* Set VCLK div */
  757. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  758. VCLK_SEL_MASK, 0);
  759. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  760. VCLK_DIV_MASK, params[freq].vclk_div - 1);
  761. /* Set HDMI-TX source */
  762. switch (hdmi_tx_div) {
  763. case 1:
  764. /* enable vclk_div1 gate */
  765. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  766. VCLK_DIV1_EN, VCLK_DIV1_EN);
  767. /* select vclk_div1 for HDMI-TX */
  768. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  769. HDMI_TX_PIXEL_SEL_MASK, 0);
  770. break;
  771. case 2:
  772. /* enable vclk_div2 gate */
  773. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  774. VCLK_DIV2_EN, VCLK_DIV2_EN);
  775. /* select vclk_div2 for HDMI-TX */
  776. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  777. HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
  778. break;
  779. case 4:
  780. /* enable vclk_div4 gate */
  781. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  782. VCLK_DIV4_EN, VCLK_DIV4_EN);
  783. /* select vclk_div4 for HDMI-TX */
  784. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  785. HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
  786. break;
  787. case 6:
  788. /* enable vclk_div6 gate */
  789. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  790. VCLK_DIV6_EN, VCLK_DIV6_EN);
  791. /* select vclk_div6 for HDMI-TX */
  792. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  793. HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
  794. break;
  795. case 12:
  796. /* enable vclk_div12 gate */
  797. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  798. VCLK_DIV12_EN, VCLK_DIV12_EN);
  799. /* select vclk_div12 for HDMI-TX */
  800. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  801. HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
  802. break;
  803. }
  804. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  805. HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
  806. /* Set ENCI/ENCP Source */
  807. switch (venc_div) {
  808. case 1:
  809. /* enable vclk_div1 gate */
  810. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  811. VCLK_DIV1_EN, VCLK_DIV1_EN);
  812. if (hdmi_use_enci)
  813. /* select vclk_div1 for enci */
  814. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  815. CTS_ENCI_SEL_MASK, 0);
  816. else
  817. /* select vclk_div1 for encp */
  818. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  819. CTS_ENCP_SEL_MASK, 0);
  820. break;
  821. case 2:
  822. /* enable vclk_div2 gate */
  823. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  824. VCLK_DIV2_EN, VCLK_DIV2_EN);
  825. if (hdmi_use_enci)
  826. /* select vclk_div2 for enci */
  827. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  828. CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
  829. else
  830. /* select vclk_div2 for encp */
  831. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  832. CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
  833. break;
  834. case 4:
  835. /* enable vclk_div4 gate */
  836. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  837. VCLK_DIV4_EN, VCLK_DIV4_EN);
  838. if (hdmi_use_enci)
  839. /* select vclk_div4 for enci */
  840. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  841. CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
  842. else
  843. /* select vclk_div4 for encp */
  844. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  845. CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
  846. break;
  847. case 6:
  848. /* enable vclk_div6 gate */
  849. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  850. VCLK_DIV6_EN, VCLK_DIV6_EN);
  851. if (hdmi_use_enci)
  852. /* select vclk_div6 for enci */
  853. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  854. CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
  855. else
  856. /* select vclk_div6 for encp */
  857. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  858. CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
  859. break;
  860. case 12:
  861. /* enable vclk_div12 gate */
  862. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  863. VCLK_DIV12_EN, VCLK_DIV12_EN);
  864. if (hdmi_use_enci)
  865. /* select vclk_div12 for enci */
  866. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  867. CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
  868. else
  869. /* select vclk_div12 for encp */
  870. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  871. CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
  872. break;
  873. }
  874. if (hdmi_use_enci)
  875. /* Enable ENCI clock gate */
  876. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  877. CTS_ENCI_EN, CTS_ENCI_EN);
  878. else
  879. /* Enable ENCP clock gate */
  880. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  881. CTS_ENCP_EN, CTS_ENCP_EN);
  882. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
  883. }
  884. EXPORT_SYMBOL_GPL(meson_vclk_setup);