meson_vclk.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  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. /* 2970 /2 /2 /2 /5 /1 => /1 /1 */
  303. #define MESON_VCLK_HDMI_74250 4
  304. /* 2970 /1 /2 /2 /5 /1 => /1 /1 */
  305. #define MESON_VCLK_HDMI_148500 5
  306. /* 2970 /1 /1 /1 /5 /2 => /1 /1 */
  307. #define MESON_VCLK_HDMI_297000 6
  308. /* 5940 /1 /1 /2 /5 /1 => /1 /1 */
  309. #define MESON_VCLK_HDMI_594000 7
  310. struct meson_vclk_params {
  311. unsigned int pll_base_freq;
  312. unsigned int pll_od1;
  313. unsigned int pll_od2;
  314. unsigned int pll_od3;
  315. unsigned int vid_pll_div;
  316. unsigned int vclk_div;
  317. } params[] = {
  318. [MESON_VCLK_HDMI_ENCI_54000] = {
  319. .pll_base_freq = 4320000,
  320. .pll_od1 = 4,
  321. .pll_od2 = 4,
  322. .pll_od3 = 1,
  323. .vid_pll_div = VID_PLL_DIV_5,
  324. .vclk_div = 1,
  325. },
  326. [MESON_VCLK_HDMI_DDR_54000] = {
  327. .pll_base_freq = 4320000,
  328. .pll_od1 = 4,
  329. .pll_od2 = 4,
  330. .pll_od3 = 1,
  331. .vid_pll_div = VID_PLL_DIV_5,
  332. .vclk_div = 1,
  333. },
  334. [MESON_VCLK_HDMI_DDR_148500] = {
  335. .pll_base_freq = 2970000,
  336. .pll_od1 = 4,
  337. .pll_od2 = 1,
  338. .pll_od3 = 1,
  339. .vid_pll_div = VID_PLL_DIV_5,
  340. .vclk_div = 1,
  341. },
  342. [MESON_VCLK_HDMI_74250] = {
  343. .pll_base_freq = 2970000,
  344. .pll_od1 = 2,
  345. .pll_od2 = 2,
  346. .pll_od3 = 2,
  347. .vid_pll_div = VID_PLL_DIV_5,
  348. .vclk_div = 1,
  349. },
  350. [MESON_VCLK_HDMI_148500] = {
  351. .pll_base_freq = 2970000,
  352. .pll_od1 = 1,
  353. .pll_od2 = 2,
  354. .pll_od3 = 2,
  355. .vid_pll_div = VID_PLL_DIV_5,
  356. .vclk_div = 1,
  357. },
  358. [MESON_VCLK_HDMI_297000] = {
  359. .pll_base_freq = 2970000,
  360. .pll_od1 = 1,
  361. .pll_od2 = 1,
  362. .pll_od3 = 1,
  363. .vid_pll_div = VID_PLL_DIV_5,
  364. .vclk_div = 2,
  365. },
  366. [MESON_VCLK_HDMI_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. };
  375. static inline unsigned int pll_od_to_reg(unsigned int od)
  376. {
  377. switch (od) {
  378. case 1:
  379. return 0;
  380. case 2:
  381. return 1;
  382. case 4:
  383. return 2;
  384. case 8:
  385. return 3;
  386. }
  387. /* Invalid */
  388. return 0;
  389. }
  390. void meson_hdmi_pll_set(struct meson_drm *priv,
  391. unsigned int base,
  392. unsigned int od1,
  393. unsigned int od2,
  394. unsigned int od3)
  395. {
  396. unsigned int val;
  397. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  398. switch (base) {
  399. case 2970000:
  400. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
  401. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  402. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  403. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  404. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  405. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  406. /* Enable and unreset */
  407. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  408. 0x7 << 28, 0x4 << 28);
  409. /* Poll for lock bit */
  410. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  411. val, (val & HDMI_PLL_LOCK), 10, 0);
  412. /* div_frac */
  413. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  414. 0xFFFF, 0x4e00);
  415. break;
  416. case 4320000:
  417. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a);
  418. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
  419. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  420. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  421. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  422. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  423. /* unreset */
  424. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  425. BIT(28), 0);
  426. /* Poll for lock bit */
  427. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  428. val, (val & HDMI_PLL_LOCK), 10, 0);
  429. break;
  430. case 5940000:
  431. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b);
  432. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  433. 0xFFFF, 0x4c00);
  434. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
  435. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  436. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  437. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  438. /* unreset */
  439. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  440. BIT(28), 0);
  441. /* Poll for lock bit */
  442. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  443. val, (val & HDMI_PLL_LOCK), 10, 0);
  444. break;
  445. };
  446. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  447. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
  448. switch (base) {
  449. case 2970000:
  450. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
  451. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
  452. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  453. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  454. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  455. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  456. break;
  457. case 4320000:
  458. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4);
  459. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
  460. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  461. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  462. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  463. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  464. break;
  465. case 5940000:
  466. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002f7);
  467. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200);
  468. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  469. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  470. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  471. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  472. break;
  473. };
  474. /* Reset PLL */
  475. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  476. HDMI_PLL_RESET, HDMI_PLL_RESET);
  477. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  478. HDMI_PLL_RESET, 0);
  479. /* Poll for lock bit */
  480. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
  481. (val & HDMI_PLL_LOCK), 10, 0);
  482. };
  483. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  484. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  485. 3 << 16, pll_od_to_reg(od1) << 16);
  486. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  487. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  488. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  489. 3 << 21, pll_od_to_reg(od1) << 21);
  490. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  491. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  492. 3 << 22, pll_od_to_reg(od2) << 22);
  493. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  494. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  495. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  496. 3 << 23, pll_od_to_reg(od2) << 23);
  497. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  498. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  499. 3 << 18, pll_od_to_reg(od3) << 18);
  500. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  501. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  502. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  503. 3 << 19, pll_od_to_reg(od3) << 19);
  504. }
  505. void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
  506. unsigned int vclk_freq, unsigned int venc_freq,
  507. unsigned int dac_freq, bool hdmi_use_enci)
  508. {
  509. unsigned int freq;
  510. unsigned int hdmi_tx_div;
  511. unsigned int venc_div;
  512. if (target == MESON_VCLK_TARGET_CVBS) {
  513. meson_venci_cvbs_clock_config(priv);
  514. return;
  515. }
  516. hdmi_tx_div = vclk_freq / dac_freq;
  517. if (hdmi_tx_div == 0) {
  518. pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
  519. dac_freq);
  520. return;
  521. }
  522. venc_div = vclk_freq / venc_freq;
  523. if (venc_div == 0) {
  524. pr_err("Fatal Error, invalid HDMI venc freq %d\n",
  525. venc_freq);
  526. return;
  527. }
  528. switch (vclk_freq) {
  529. case 54000:
  530. if (hdmi_use_enci)
  531. freq = MESON_VCLK_HDMI_ENCI_54000;
  532. else
  533. freq = MESON_VCLK_HDMI_DDR_54000;
  534. break;
  535. case 74250:
  536. freq = MESON_VCLK_HDMI_74250;
  537. break;
  538. case 148500:
  539. if (dac_freq != 148500)
  540. freq = MESON_VCLK_HDMI_DDR_148500;
  541. else
  542. freq = MESON_VCLK_HDMI_148500;
  543. break;
  544. case 297000:
  545. freq = MESON_VCLK_HDMI_297000;
  546. break;
  547. case 594000:
  548. freq = MESON_VCLK_HDMI_594000;
  549. break;
  550. default:
  551. pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
  552. vclk_freq);
  553. return;
  554. }
  555. /* Set HDMI-TX sys clock */
  556. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  557. CTS_HDMI_SYS_SEL_MASK, 0);
  558. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  559. CTS_HDMI_SYS_DIV_MASK, 0);
  560. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  561. CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
  562. /* Set HDMI PLL rate */
  563. meson_hdmi_pll_set(priv, params[freq].pll_base_freq,
  564. params[freq].pll_od1,
  565. params[freq].pll_od2,
  566. params[freq].pll_od3);
  567. /* Setup vid_pll divider */
  568. meson_vid_pll_set(priv, params[freq].vid_pll_div);
  569. /* Set VCLK div */
  570. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  571. VCLK_SEL_MASK, 0);
  572. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  573. VCLK_DIV_MASK, params[freq].vclk_div - 1);
  574. /* Set HDMI-TX source */
  575. switch (hdmi_tx_div) {
  576. case 1:
  577. /* enable vclk_div1 gate */
  578. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  579. VCLK_DIV1_EN, VCLK_DIV1_EN);
  580. /* select vclk_div1 for HDMI-TX */
  581. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  582. HDMI_TX_PIXEL_SEL_MASK, 0);
  583. break;
  584. case 2:
  585. /* enable vclk_div2 gate */
  586. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  587. VCLK_DIV2_EN, VCLK_DIV2_EN);
  588. /* select vclk_div2 for HDMI-TX */
  589. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  590. HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
  591. break;
  592. case 4:
  593. /* enable vclk_div4 gate */
  594. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  595. VCLK_DIV4_EN, VCLK_DIV4_EN);
  596. /* select vclk_div4 for HDMI-TX */
  597. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  598. HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
  599. break;
  600. case 6:
  601. /* enable vclk_div6 gate */
  602. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  603. VCLK_DIV6_EN, VCLK_DIV6_EN);
  604. /* select vclk_div6 for HDMI-TX */
  605. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  606. HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
  607. break;
  608. case 12:
  609. /* enable vclk_div12 gate */
  610. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  611. VCLK_DIV12_EN, VCLK_DIV12_EN);
  612. /* select vclk_div12 for HDMI-TX */
  613. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  614. HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
  615. break;
  616. }
  617. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  618. HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
  619. /* Set ENCI/ENCP Source */
  620. switch (venc_div) {
  621. case 1:
  622. /* enable vclk_div1 gate */
  623. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  624. VCLK_DIV1_EN, VCLK_DIV1_EN);
  625. if (hdmi_use_enci)
  626. /* select vclk_div1 for enci */
  627. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  628. CTS_ENCI_SEL_MASK, 0);
  629. else
  630. /* select vclk_div1 for encp */
  631. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  632. CTS_ENCP_SEL_MASK, 0);
  633. break;
  634. case 2:
  635. /* enable vclk_div2 gate */
  636. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  637. VCLK_DIV2_EN, VCLK_DIV2_EN);
  638. if (hdmi_use_enci)
  639. /* select vclk_div2 for enci */
  640. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  641. CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
  642. else
  643. /* select vclk_div2 for encp */
  644. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  645. CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
  646. break;
  647. case 4:
  648. /* enable vclk_div4 gate */
  649. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  650. VCLK_DIV4_EN, VCLK_DIV4_EN);
  651. if (hdmi_use_enci)
  652. /* select vclk_div4 for enci */
  653. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  654. CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
  655. else
  656. /* select vclk_div4 for encp */
  657. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  658. CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
  659. break;
  660. case 6:
  661. /* enable vclk_div6 gate */
  662. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  663. VCLK_DIV6_EN, VCLK_DIV6_EN);
  664. if (hdmi_use_enci)
  665. /* select vclk_div6 for enci */
  666. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  667. CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
  668. else
  669. /* select vclk_div6 for encp */
  670. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  671. CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
  672. break;
  673. case 12:
  674. /* enable vclk_div12 gate */
  675. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  676. VCLK_DIV12_EN, VCLK_DIV12_EN);
  677. if (hdmi_use_enci)
  678. /* select vclk_div12 for enci */
  679. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  680. CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
  681. else
  682. /* select vclk_div12 for encp */
  683. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  684. CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
  685. break;
  686. }
  687. if (hdmi_use_enci)
  688. /* Enable ENCI clock gate */
  689. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  690. CTS_ENCI_EN, CTS_ENCI_EN);
  691. else
  692. /* Enable ENCP clock gate */
  693. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  694. CTS_ENCP_EN, CTS_ENCP_EN);
  695. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
  696. }
  697. EXPORT_SYMBOL_GPL(meson_vclk_setup);