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