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