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