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