meson_vclk.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  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. enum {
  296. /* PLL O1 O2 O3 VP DV EN TX */
  297. /* 4320 /4 /4 /1 /5 /1 => /2 /2 */
  298. MESON_VCLK_HDMI_ENCI_54000 = 1,
  299. /* 4320 /4 /4 /1 /5 /1 => /1 /2 */
  300. MESON_VCLK_HDMI_DDR_54000,
  301. /* 2970 /4 /1 /1 /5 /1 => /1 /2 */
  302. MESON_VCLK_HDMI_DDR_148500,
  303. /* 2970 /2 /2 /2 /5 /1 => /1 /1 */
  304. MESON_VCLK_HDMI_74250,
  305. /* 2970 /1 /2 /2 /5 /1 => /1 /1 */
  306. MESON_VCLK_HDMI_148500,
  307. /* 2970 /1 /1 /1 /5 /2 => /1 /1 */
  308. MESON_VCLK_HDMI_297000,
  309. /* 5940 /1 /1 /2 /5 /1 => /1 /1 */
  310. MESON_VCLK_HDMI_594000
  311. };
  312. struct meson_vclk_params {
  313. unsigned int pll_base_freq;
  314. unsigned int pll_od1;
  315. unsigned int pll_od2;
  316. unsigned int pll_od3;
  317. unsigned int vid_pll_div;
  318. unsigned int vclk_div;
  319. } params[] = {
  320. [MESON_VCLK_HDMI_ENCI_54000] = {
  321. .pll_base_freq = 4320000,
  322. .pll_od1 = 4,
  323. .pll_od2 = 4,
  324. .pll_od3 = 1,
  325. .vid_pll_div = VID_PLL_DIV_5,
  326. .vclk_div = 1,
  327. },
  328. [MESON_VCLK_HDMI_DDR_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_148500] = {
  337. .pll_base_freq = 2970000,
  338. .pll_od1 = 4,
  339. .pll_od2 = 1,
  340. .pll_od3 = 1,
  341. .vid_pll_div = VID_PLL_DIV_5,
  342. .vclk_div = 1,
  343. },
  344. [MESON_VCLK_HDMI_74250] = {
  345. .pll_base_freq = 2970000,
  346. .pll_od1 = 2,
  347. .pll_od2 = 2,
  348. .pll_od3 = 2,
  349. .vid_pll_div = VID_PLL_DIV_5,
  350. .vclk_div = 1,
  351. },
  352. [MESON_VCLK_HDMI_148500] = {
  353. .pll_base_freq = 2970000,
  354. .pll_od1 = 1,
  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_297000] = {
  361. .pll_base_freq = 2970000,
  362. .pll_od1 = 1,
  363. .pll_od2 = 1,
  364. .pll_od3 = 1,
  365. .vid_pll_div = VID_PLL_DIV_5,
  366. .vclk_div = 2,
  367. },
  368. [MESON_VCLK_HDMI_594000] = {
  369. .pll_base_freq = 5940000,
  370. .pll_od1 = 1,
  371. .pll_od2 = 1,
  372. .pll_od3 = 2,
  373. .vid_pll_div = VID_PLL_DIV_5,
  374. .vclk_div = 1,
  375. },
  376. };
  377. static inline unsigned int pll_od_to_reg(unsigned int od)
  378. {
  379. switch (od) {
  380. case 1:
  381. return 0;
  382. case 2:
  383. return 1;
  384. case 4:
  385. return 2;
  386. case 8:
  387. return 3;
  388. }
  389. /* Invalid */
  390. return 0;
  391. }
  392. void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
  393. unsigned int frac, unsigned int od1,
  394. unsigned int od2, unsigned int od3)
  395. {
  396. unsigned int val;
  397. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  398. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m);
  399. if (frac)
  400. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
  401. 0x00004000 | frac);
  402. else
  403. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
  404. 0x00000000);
  405. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
  406. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
  407. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
  408. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
  409. /* Enable and unreset */
  410. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  411. 0x7 << 28, 0x4 << 28);
  412. /* Poll for lock bit */
  413. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
  414. val, (val & HDMI_PLL_LOCK), 10, 0);
  415. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  416. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
  417. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m);
  418. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
  419. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
  420. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
  421. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
  422. regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
  423. /* Reset PLL */
  424. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  425. HDMI_PLL_RESET, HDMI_PLL_RESET);
  426. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
  427. HDMI_PLL_RESET, 0);
  428. /* Poll for lock bit */
  429. regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
  430. (val & HDMI_PLL_LOCK), 10, 0);
  431. }
  432. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  433. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  434. 3 << 16, pll_od_to_reg(od1) << 16);
  435. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  436. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  437. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  438. 3 << 21, pll_od_to_reg(od1) << 21);
  439. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  440. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  441. 3 << 22, pll_od_to_reg(od2) << 22);
  442. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  443. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  444. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  445. 3 << 23, pll_od_to_reg(od2) << 23);
  446. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  447. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
  448. 3 << 18, pll_od_to_reg(od3) << 18);
  449. else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  450. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
  451. regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
  452. 3 << 19, pll_od_to_reg(od3) << 19);
  453. }
  454. #define XTAL_FREQ 24000
  455. static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
  456. unsigned int pll_freq)
  457. {
  458. /* The GXBB PLL has a /2 pre-multiplier */
  459. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
  460. pll_freq /= 2;
  461. return pll_freq / XTAL_FREQ;
  462. }
  463. #define HDMI_FRAC_MAX_GXBB 4096
  464. #define HDMI_FRAC_MAX_GXL 1024
  465. static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
  466. unsigned int m,
  467. unsigned int pll_freq)
  468. {
  469. unsigned int parent_freq = XTAL_FREQ;
  470. unsigned int frac_max = HDMI_FRAC_MAX_GXL;
  471. unsigned int frac_m;
  472. unsigned int frac;
  473. /* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
  474. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  475. frac_max = HDMI_FRAC_MAX_GXBB;
  476. parent_freq *= 2;
  477. }
  478. /* We can have a perfect match !*/
  479. if (pll_freq / m == parent_freq &&
  480. pll_freq % m == 0)
  481. return 0;
  482. frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
  483. frac_m = m * frac_max;
  484. if (frac_m > frac)
  485. return frac_max;
  486. frac -= frac_m;
  487. return min((u16)frac, (u16)(frac_max - 1));
  488. }
  489. static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
  490. unsigned int m,
  491. unsigned int frac)
  492. {
  493. if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  494. /* Empiric supported min/max dividers */
  495. if (m < 53 || m > 123)
  496. return false;
  497. if (frac >= HDMI_FRAC_MAX_GXBB)
  498. return false;
  499. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  500. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
  501. /* Empiric supported min/max dividers */
  502. if (m < 106 || m > 247)
  503. return false;
  504. if (frac >= HDMI_FRAC_MAX_GXL)
  505. return false;
  506. }
  507. return true;
  508. }
  509. static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
  510. unsigned int freq,
  511. unsigned int *m,
  512. unsigned int *frac,
  513. unsigned int *od)
  514. {
  515. /* Cycle from /16 to /2 */
  516. for (*od = 16 ; *od > 1 ; *od >>= 1) {
  517. *m = meson_hdmi_pll_get_m(priv, freq * *od);
  518. if (!*m)
  519. continue;
  520. *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
  521. DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n",
  522. freq, *m, *frac, *od);
  523. if (meson_hdmi_pll_validate_params(priv, *m, *frac))
  524. return true;
  525. }
  526. return false;
  527. }
  528. /* pll_freq is the frequency after the OD dividers */
  529. enum drm_mode_status
  530. meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
  531. {
  532. unsigned int od, m, frac;
  533. /* In DMT mode, path after PLL is always /10 */
  534. freq *= 10;
  535. if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
  536. return MODE_OK;
  537. return MODE_CLOCK_RANGE;
  538. }
  539. EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
  540. /* pll_freq is the frequency after the OD dividers */
  541. static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
  542. unsigned int pll_freq)
  543. {
  544. unsigned int od, m, frac, od1, od2, od3;
  545. if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
  546. od3 = 1;
  547. if (od < 4) {
  548. od1 = 2;
  549. od2 = 1;
  550. } else {
  551. od2 = od / 4;
  552. od1 = od / od2;
  553. }
  554. DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
  555. pll_freq, m, frac, od1, od2, od3);
  556. meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
  557. return;
  558. }
  559. DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n",
  560. pll_freq);
  561. }
  562. static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
  563. unsigned int od1, unsigned int od2, unsigned int od3,
  564. unsigned int vid_pll_div, unsigned int vclk_div,
  565. unsigned int hdmi_tx_div, unsigned int venc_div,
  566. bool hdmi_use_enci)
  567. {
  568. /* Set HDMI-TX sys clock */
  569. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  570. CTS_HDMI_SYS_SEL_MASK, 0);
  571. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  572. CTS_HDMI_SYS_DIV_MASK, 0);
  573. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  574. CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
  575. /* Set HDMI PLL rate */
  576. if (!od1 && !od2 && !od3) {
  577. meson_hdmi_pll_generic_set(priv, pll_base_freq);
  578. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
  579. switch (pll_base_freq) {
  580. case 2970000:
  581. meson_hdmi_pll_set_params(priv, 0x3d, 0xe00,
  582. od1, od2, od3);
  583. break;
  584. case 4320000:
  585. meson_hdmi_pll_set_params(priv, 0x5a, 0,
  586. od1, od2, od3);
  587. break;
  588. case 5940000:
  589. meson_hdmi_pll_set_params(priv, 0x7b, 0xc00,
  590. od1, od2, od3);
  591. break;
  592. }
  593. } else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
  594. meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
  595. switch (pll_base_freq) {
  596. case 2970000:
  597. meson_hdmi_pll_set_params(priv, 0x7b, 0x300,
  598. od1, od2, od3);
  599. break;
  600. case 4320000:
  601. meson_hdmi_pll_set_params(priv, 0xb4, 0,
  602. od1, od2, od3);
  603. break;
  604. case 5940000:
  605. meson_hdmi_pll_set_params(priv, 0xf7, 0x200,
  606. od1, od2, od3);
  607. break;
  608. }
  609. }
  610. /* Setup vid_pll divider */
  611. meson_vid_pll_set(priv, vid_pll_div);
  612. /* Set VCLK div */
  613. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  614. VCLK_SEL_MASK, 0);
  615. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  616. VCLK_DIV_MASK, vclk_div - 1);
  617. /* Set HDMI-TX source */
  618. switch (hdmi_tx_div) {
  619. case 1:
  620. /* enable vclk_div1 gate */
  621. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  622. VCLK_DIV1_EN, VCLK_DIV1_EN);
  623. /* select vclk_div1 for HDMI-TX */
  624. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  625. HDMI_TX_PIXEL_SEL_MASK, 0);
  626. break;
  627. case 2:
  628. /* enable vclk_div2 gate */
  629. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  630. VCLK_DIV2_EN, VCLK_DIV2_EN);
  631. /* select vclk_div2 for HDMI-TX */
  632. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  633. HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
  634. break;
  635. case 4:
  636. /* enable vclk_div4 gate */
  637. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  638. VCLK_DIV4_EN, VCLK_DIV4_EN);
  639. /* select vclk_div4 for HDMI-TX */
  640. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  641. HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
  642. break;
  643. case 6:
  644. /* enable vclk_div6 gate */
  645. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  646. VCLK_DIV6_EN, VCLK_DIV6_EN);
  647. /* select vclk_div6 for HDMI-TX */
  648. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  649. HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
  650. break;
  651. case 12:
  652. /* enable vclk_div12 gate */
  653. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  654. VCLK_DIV12_EN, VCLK_DIV12_EN);
  655. /* select vclk_div12 for HDMI-TX */
  656. regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
  657. HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
  658. break;
  659. }
  660. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  661. HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
  662. /* Set ENCI/ENCP Source */
  663. switch (venc_div) {
  664. case 1:
  665. /* enable vclk_div1 gate */
  666. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  667. VCLK_DIV1_EN, VCLK_DIV1_EN);
  668. if (hdmi_use_enci)
  669. /* select vclk_div1 for enci */
  670. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  671. CTS_ENCI_SEL_MASK, 0);
  672. else
  673. /* select vclk_div1 for encp */
  674. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  675. CTS_ENCP_SEL_MASK, 0);
  676. break;
  677. case 2:
  678. /* enable vclk_div2 gate */
  679. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  680. VCLK_DIV2_EN, VCLK_DIV2_EN);
  681. if (hdmi_use_enci)
  682. /* select vclk_div2 for enci */
  683. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  684. CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
  685. else
  686. /* select vclk_div2 for encp */
  687. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  688. CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
  689. break;
  690. case 4:
  691. /* enable vclk_div4 gate */
  692. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  693. VCLK_DIV4_EN, VCLK_DIV4_EN);
  694. if (hdmi_use_enci)
  695. /* select vclk_div4 for enci */
  696. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  697. CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
  698. else
  699. /* select vclk_div4 for encp */
  700. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  701. CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
  702. break;
  703. case 6:
  704. /* enable vclk_div6 gate */
  705. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  706. VCLK_DIV6_EN, VCLK_DIV6_EN);
  707. if (hdmi_use_enci)
  708. /* select vclk_div6 for enci */
  709. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  710. CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
  711. else
  712. /* select vclk_div6 for encp */
  713. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  714. CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
  715. break;
  716. case 12:
  717. /* enable vclk_div12 gate */
  718. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
  719. VCLK_DIV12_EN, VCLK_DIV12_EN);
  720. if (hdmi_use_enci)
  721. /* select vclk_div12 for enci */
  722. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  723. CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
  724. else
  725. /* select vclk_div12 for encp */
  726. regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
  727. CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
  728. break;
  729. }
  730. if (hdmi_use_enci)
  731. /* Enable ENCI clock gate */
  732. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  733. CTS_ENCI_EN, CTS_ENCI_EN);
  734. else
  735. /* Enable ENCP clock gate */
  736. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
  737. CTS_ENCP_EN, CTS_ENCP_EN);
  738. regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
  739. }
  740. void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
  741. unsigned int vclk_freq, unsigned int venc_freq,
  742. unsigned int dac_freq, bool hdmi_use_enci)
  743. {
  744. unsigned int freq;
  745. unsigned int hdmi_tx_div;
  746. unsigned int venc_div;
  747. if (target == MESON_VCLK_TARGET_CVBS) {
  748. meson_venci_cvbs_clock_config(priv);
  749. return;
  750. } else if (target == MESON_VCLK_TARGET_DMT) {
  751. /* The DMT clock path is fixed after the PLL:
  752. * - automatic PLL freq + OD management
  753. * - vid_pll_div = VID_PLL_DIV_5
  754. * - vclk_div = 2
  755. * - hdmi_tx_div = 1
  756. * - venc_div = 1
  757. * - encp encoder
  758. */
  759. meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
  760. VID_PLL_DIV_5, 2, 1, 1, false);
  761. return;
  762. }
  763. hdmi_tx_div = vclk_freq / dac_freq;
  764. if (hdmi_tx_div == 0) {
  765. pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
  766. dac_freq);
  767. return;
  768. }
  769. venc_div = vclk_freq / venc_freq;
  770. if (venc_div == 0) {
  771. pr_err("Fatal Error, invalid HDMI venc freq %d\n",
  772. venc_freq);
  773. return;
  774. }
  775. switch (vclk_freq) {
  776. case 54000:
  777. if (hdmi_use_enci)
  778. freq = MESON_VCLK_HDMI_ENCI_54000;
  779. else
  780. freq = MESON_VCLK_HDMI_DDR_54000;
  781. break;
  782. case 74250:
  783. freq = MESON_VCLK_HDMI_74250;
  784. break;
  785. case 148500:
  786. if (dac_freq != 148500)
  787. freq = MESON_VCLK_HDMI_DDR_148500;
  788. else
  789. freq = MESON_VCLK_HDMI_148500;
  790. break;
  791. case 297000:
  792. freq = MESON_VCLK_HDMI_297000;
  793. break;
  794. case 594000:
  795. freq = MESON_VCLK_HDMI_594000;
  796. break;
  797. default:
  798. pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
  799. vclk_freq);
  800. return;
  801. }
  802. meson_vclk_set(priv, params[freq].pll_base_freq,
  803. params[freq].pll_od1, params[freq].pll_od2,
  804. params[freq].pll_od3, params[freq].vid_pll_div,
  805. params[freq].vclk_div, hdmi_tx_div, venc_div,
  806. hdmi_use_enci);
  807. }
  808. EXPORT_SYMBOL_GPL(meson_vclk_setup);