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