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