linux/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2015 Broadcom
   4 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
   5 * Copyright (C) 2013 Red Hat
   6 * Author: Rob Clark <robdclark@gmail.com>
   7 */
   8
   9#include "vc4_hdmi.h"
  10#include "vc4_regs.h"
  11#include "vc4_hdmi_regs.h"
  12
  13#define VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB    BIT(5)
  14#define VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB BIT(4)
  15#define VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET   BIT(3)
  16#define VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET    BIT(2)
  17#define VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET    BIT(1)
  18#define VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET    BIT(0)
  19
  20#define VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN      BIT(4)
  21
  22#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_SHIFT     29
  23#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_MASK      VC4_MASK(31, 29)
  24#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_SHIFT    24
  25#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_MASK     VC4_MASK(28, 24)
  26#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_SHIFT     21
  27#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_MASK      VC4_MASK(23, 21)
  28#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_SHIFT    16
  29#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_MASK     VC4_MASK(20, 16)
  30#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_SHIFT     13
  31#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_MASK      VC4_MASK(15, 13)
  32#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_SHIFT    8
  33#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_MASK     VC4_MASK(12, 8)
  34#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_SHIFT    5
  35#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_MASK     VC4_MASK(7, 5)
  36#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_SHIFT   0
  37#define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_MASK    VC4_MASK(4, 0)
  38
  39#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_SHIFT       15
  40#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_MASK        VC4_MASK(19, 15)
  41#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_SHIFT       10
  42#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_MASK        VC4_MASK(14, 10)
  43#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_SHIFT       5
  44#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_MASK        VC4_MASK(9, 5)
  45#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_SHIFT          0
  46#define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_MASK           VC4_MASK(4, 0)
  47
  48#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_SHIFT            16
  49#define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_MASK             VC4_MASK(19, 16)
  50#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_SHIFT   12
  51#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_MASK    VC4_MASK(15, 12)
  52#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_SHIFT   8
  53#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_MASK    VC4_MASK(11, 8)
  54#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_SHIFT   4
  55#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_MASK    VC4_MASK(7, 4)
  56#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_SHIFT      0
  57#define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_MASK       VC4_MASK(3, 0)
  58
  59#define VC4_HDMI_TX_PHY_CTL_3_RP_SHIFT                  17
  60#define VC4_HDMI_TX_PHY_CTL_3_RP_MASK                   VC4_MASK(19, 17)
  61#define VC4_HDMI_TX_PHY_CTL_3_RZ_SHIFT                  12
  62#define VC4_HDMI_TX_PHY_CTL_3_RZ_MASK                   VC4_MASK(16, 12)
  63#define VC4_HDMI_TX_PHY_CTL_3_CP1_SHIFT                 10
  64#define VC4_HDMI_TX_PHY_CTL_3_CP1_MASK                  VC4_MASK(11, 10)
  65#define VC4_HDMI_TX_PHY_CTL_3_CP_SHIFT                  8
  66#define VC4_HDMI_TX_PHY_CTL_3_CP_MASK                   VC4_MASK(9, 8)
  67#define VC4_HDMI_TX_PHY_CTL_3_CZ_SHIFT                  6
  68#define VC4_HDMI_TX_PHY_CTL_3_CZ_MASK                   VC4_MASK(7, 6)
  69#define VC4_HDMI_TX_PHY_CTL_3_ICP_SHIFT                 0
  70#define VC4_HDMI_TX_PHY_CTL_3_ICP_MASK                  VC4_MASK(5, 0)
  71
  72#define VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE           BIT(13)
  73#define VC4_HDMI_TX_PHY_PLL_CTL_0_VC_RANGE_EN           BIT(12)
  74#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_LOW        BIT(11)
  75#define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_HIGH       BIT(10)
  76#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_SHIFT         9
  77#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_MASK          VC4_MASK(9, 9)
  78#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_FB_DIV2           BIT(8)
  79#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_POST_DIV2         BIT(7)
  80#define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN           BIT(6)
  81#define VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK           BIT(5)
  82
  83#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_SHIFT                     16
  84#define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_MASK                      VC4_MASK(27, 16)
  85#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_SHIFT      14
  86#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_MASK       VC4_MASK(15, 14)
  87#define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE           BIT(13)
  88#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_SHIFT            11
  89#define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_MASK             VC4_MASK(12, 11)
  90
  91#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_SHIFT               8
  92#define VC4_HDMI_TX_PHY_CLK_DIV_VCO_MASK                VC4_MASK(15, 8)
  93
  94#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_SHIFT              0
  95#define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_MASK               VC4_MASK(3, 0)
  96
  97#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_MASK  VC4_MASK(13, 12)
  98#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_SHIFT 12
  99#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_MASK   VC4_MASK(9, 8)
 100#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_SHIFT  8
 101#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_MASK   VC4_MASK(5, 4)
 102#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_SHIFT  4
 103#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_MASK   VC4_MASK(1, 0)
 104#define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_SHIFT  0
 105
 106#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK         VC4_MASK(27, 0)
 107#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_SHIFT        0
 108
 109#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK         VC4_MASK(27, 0)
 110#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_SHIFT        0
 111
 112#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_MASK  VC4_MASK(31, 16)
 113#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_SHIFT 16
 114#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_MASK    VC4_MASK(15, 0)
 115#define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_SHIFT   0
 116
 117#define VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS          BIT(19)
 118#define VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR          BIT(17)
 119#define VC4_HDMI_RM_CONTROL_FREE_RUN                    BIT(4)
 120
 121#define VC4_HDMI_RM_OFFSET_ONLY                         BIT(31)
 122#define VC4_HDMI_RM_OFFSET_OFFSET_SHIFT                 0
 123#define VC4_HDMI_RM_OFFSET_OFFSET_MASK                  VC4_MASK(30, 0)
 124
 125#define VC4_HDMI_RM_FORMAT_SHIFT_SHIFT                  24
 126#define VC4_HDMI_RM_FORMAT_SHIFT_MASK                   VC4_MASK(25, 24)
 127
 128#define OSCILLATOR_FREQUENCY    54000000
 129
 130void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
 131                       struct vc4_hdmi_connector_state *conn_state)
 132{
 133        /* PHY should be in reset, like
 134         * vc4_hdmi_encoder_disable() does.
 135         */
 136
 137        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
 138        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
 139}
 140
 141void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
 142{
 143        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
 144}
 145
 146void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
 147{
 148        HDMI_WRITE(HDMI_TX_PHY_CTL_0,
 149                   HDMI_READ(HDMI_TX_PHY_CTL_0) &
 150                   ~VC4_HDMI_TX_PHY_RNG_PWRDN);
 151}
 152
 153void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
 154{
 155        HDMI_WRITE(HDMI_TX_PHY_CTL_0,
 156                   HDMI_READ(HDMI_TX_PHY_CTL_0) |
 157                   VC4_HDMI_TX_PHY_RNG_PWRDN);
 158}
 159
 160static unsigned long long
 161phy_get_vco_freq(unsigned long long clock, u8 *vco_sel, u8 *vco_div)
 162{
 163        unsigned long long vco_freq = clock;
 164        unsigned int _vco_div = 0;
 165        unsigned int _vco_sel = 0;
 166
 167        while (vco_freq < 3000000000ULL) {
 168                _vco_div++;
 169                vco_freq = clock * _vco_div * 10;
 170        }
 171
 172        if (vco_freq > 4500000000ULL)
 173                _vco_sel = 1;
 174
 175        *vco_sel = _vco_sel;
 176        *vco_div = _vco_div;
 177
 178        return vco_freq;
 179}
 180
 181static u8 phy_get_cp_current(unsigned long vco_freq)
 182{
 183        if (vco_freq < 3700000000ULL)
 184                return 0x1c;
 185
 186        return 0x18;
 187}
 188
 189static u32 phy_get_rm_offset(unsigned long long vco_freq)
 190{
 191        unsigned long long fref = OSCILLATOR_FREQUENCY;
 192        u64 offset = 0;
 193
 194        /* RM offset is stored as 9.22 format */
 195        offset = vco_freq * 2;
 196        offset = offset << 22;
 197        do_div(offset, fref);
 198        offset >>= 2;
 199
 200        return offset;
 201}
 202
 203static u8 phy_get_vco_gain(unsigned long long vco_freq)
 204{
 205        if (vco_freq < 3350000000ULL)
 206                return 0xf;
 207
 208        if (vco_freq < 3700000000ULL)
 209                return 0xc;
 210
 211        if (vco_freq < 4050000000ULL)
 212                return 0x6;
 213
 214        if (vco_freq < 4800000000ULL)
 215                return 0x5;
 216
 217        if (vco_freq < 5200000000ULL)
 218                return 0x7;
 219
 220        return 0x2;
 221}
 222
 223struct phy_lane_settings {
 224        struct {
 225                u8 preemphasis;
 226                u8 main_driver;
 227        } amplitude;
 228
 229        u8 res_sel_data;
 230        u8 term_res_sel_data;
 231};
 232
 233struct phy_settings {
 234        unsigned long long min_rate;
 235        unsigned long long max_rate;
 236        struct phy_lane_settings channel[3];
 237        struct phy_lane_settings clock;
 238};
 239
 240static const struct phy_settings vc5_hdmi_phy_settings[] = {
 241        {
 242                0, 50000000,
 243                {
 244                        {{0x0, 0x0A}, 0x12, 0x0},
 245                        {{0x0, 0x0A}, 0x12, 0x0},
 246                        {{0x0, 0x0A}, 0x12, 0x0}
 247                },
 248                {{0x0, 0x0A}, 0x18, 0x0},
 249        },
 250        {
 251                50000001, 75000000,
 252                {
 253                        {{0x0, 0x09}, 0x12, 0x0},
 254                        {{0x0, 0x09}, 0x12, 0x0},
 255                        {{0x0, 0x09}, 0x12, 0x0}
 256                },
 257                {{0x0, 0x0C}, 0x18, 0x3},
 258        },
 259        {
 260                75000001,   165000000,
 261                {
 262                        {{0x0, 0x09}, 0x12, 0x0},
 263                        {{0x0, 0x09}, 0x12, 0x0},
 264                        {{0x0, 0x09}, 0x12, 0x0}
 265                },
 266                {{0x0, 0x0C}, 0x18, 0x3},
 267        },
 268        {
 269                165000001,  250000000,
 270                {
 271                        {{0x0, 0x0F}, 0x12, 0x1},
 272                        {{0x0, 0x0F}, 0x12, 0x1},
 273                        {{0x0, 0x0F}, 0x12, 0x1}
 274                },
 275                {{0x0, 0x0C}, 0x18, 0x3},
 276        },
 277        {
 278                250000001,  340000000,
 279                {
 280                        {{0x2, 0x0D}, 0x12, 0x1},
 281                        {{0x2, 0x0D}, 0x12, 0x1},
 282                        {{0x2, 0x0D}, 0x12, 0x1}
 283                },
 284                {{0x0, 0x0C}, 0x18, 0xF},
 285        },
 286        {
 287                340000001,  450000000,
 288                {
 289                        {{0x0, 0x1B}, 0x12, 0xF},
 290                        {{0x0, 0x1B}, 0x12, 0xF},
 291                        {{0x0, 0x1B}, 0x12, 0xF}
 292                },
 293                {{0x0, 0x0A}, 0x12, 0xF},
 294        },
 295        {
 296                450000001,  600000000,
 297                {
 298                        {{0x0, 0x1C}, 0x12, 0xF},
 299                        {{0x0, 0x1C}, 0x12, 0xF},
 300                        {{0x0, 0x1C}, 0x12, 0xF}
 301                },
 302                {{0x0, 0x0B}, 0x13, 0xF},
 303        },
 304};
 305
 306static const struct phy_settings *phy_get_settings(unsigned long long tmds_rate)
 307{
 308        unsigned int count = ARRAY_SIZE(vc5_hdmi_phy_settings);
 309        unsigned int i;
 310
 311        for (i = 0; i < count; i++) {
 312                const struct phy_settings *s = &vc5_hdmi_phy_settings[i];
 313
 314                if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate)
 315                        return s;
 316        }
 317
 318        /*
 319         * If the pixel clock exceeds our max setting, try the max
 320         * setting anyway.
 321         */
 322        return &vc5_hdmi_phy_settings[count - 1];
 323}
 324
 325static const struct phy_lane_settings *
 326phy_get_channel_settings(enum vc4_hdmi_phy_channel chan,
 327                         unsigned long long tmds_rate)
 328{
 329        const struct phy_settings *settings = phy_get_settings(tmds_rate);
 330
 331        if (chan == PHY_LANE_CK)
 332                return &settings->clock;
 333
 334        return &settings->channel[chan];
 335}
 336
 337static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
 338{
 339        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f);
 340        HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10));
 341}
 342
 343void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
 344                       struct vc4_hdmi_connector_state *conn_state)
 345{
 346        const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
 347        const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
 348        unsigned long long pixel_freq = conn_state->pixel_rate;
 349        unsigned long long vco_freq;
 350        unsigned char word_sel;
 351        u8 vco_sel, vco_div;
 352
 353        vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div);
 354
 355        vc5_hdmi_reset_phy(vc4_hdmi);
 356
 357        HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
 358                   VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
 359
 360        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
 361                   HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
 362                   ~VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET &
 363                   ~VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET &
 364                   ~VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET &
 365                   ~VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET);
 366
 367        HDMI_WRITE(HDMI_RM_CONTROL,
 368                   HDMI_READ(HDMI_RM_CONTROL) |
 369                   VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS |
 370                   VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR |
 371                   VC4_HDMI_RM_CONTROL_FREE_RUN);
 372
 373        HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
 374                   (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1) &
 375                    ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK) |
 376                   VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT));
 377
 378        HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
 379                   (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2) &
 380                    ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK) |
 381                   VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT));
 382
 383        HDMI_WRITE(HDMI_RM_OFFSET,
 384                   VC4_SET_FIELD(phy_get_rm_offset(vco_freq),
 385                                 VC4_HDMI_RM_OFFSET_OFFSET) |
 386                   VC4_HDMI_RM_OFFSET_ONLY);
 387
 388        HDMI_WRITE(HDMI_TX_PHY_CLK_DIV,
 389                   VC4_SET_FIELD(vco_div, VC4_HDMI_TX_PHY_CLK_DIV_VCO));
 390
 391        HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
 392                   VC4_SET_FIELD(0xe147, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD) |
 393                   VC4_SET_FIELD(0xe14, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD));
 394
 395        HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_0,
 396                   VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK |
 397                   VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN |
 398                   VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE |
 399                   VC4_SET_FIELD(vco_sel, VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL));
 400
 401        HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_1,
 402                   HDMI_READ(HDMI_TX_PHY_PLL_CTL_1) |
 403                   VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE |
 404                   VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL) |
 405                   VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY) |
 406                   VC4_SET_FIELD(0x8a, VC4_HDMI_TX_PHY_PLL_CTL_1_CPP));
 407
 408        HDMI_WRITE(HDMI_RM_FORMAT,
 409                   HDMI_READ(HDMI_RM_FORMAT) |
 410                   VC4_SET_FIELD(2, VC4_HDMI_RM_FORMAT_SHIFT));
 411
 412        HDMI_WRITE(HDMI_TX_PHY_PLL_CFG,
 413                   HDMI_READ(HDMI_TX_PHY_PLL_CFG) |
 414                   VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CFG_PDIV));
 415
 416        if (pixel_freq >= 340000000)
 417                word_sel = 3;
 418        else
 419                word_sel = 0;
 420        HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel);
 421
 422        HDMI_WRITE(HDMI_TX_PHY_CTL_3,
 423                   VC4_SET_FIELD(phy_get_cp_current(vco_freq),
 424                                 VC4_HDMI_TX_PHY_CTL_3_ICP) |
 425                   VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP) |
 426                   VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP1) |
 427                   VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_CTL_3_CZ) |
 428                   VC4_SET_FIELD(4, VC4_HDMI_TX_PHY_CTL_3_RP) |
 429                   VC4_SET_FIELD(6, VC4_HDMI_TX_PHY_CTL_3_RZ));
 430
 431        chan0_settings =
 432                phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0],
 433                                         pixel_freq);
 434        chan1_settings =
 435                phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1],
 436                                         pixel_freq);
 437        chan2_settings =
 438                phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2],
 439                                         pixel_freq);
 440        clock_settings =
 441                phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK],
 442                                         pixel_freq);
 443
 444        HDMI_WRITE(HDMI_TX_PHY_CTL_0,
 445                   VC4_SET_FIELD(chan0_settings->amplitude.preemphasis,
 446                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP) |
 447                   VC4_SET_FIELD(chan0_settings->amplitude.main_driver,
 448                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV) |
 449                   VC4_SET_FIELD(chan1_settings->amplitude.preemphasis,
 450                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP) |
 451                   VC4_SET_FIELD(chan1_settings->amplitude.main_driver,
 452                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV) |
 453                   VC4_SET_FIELD(chan2_settings->amplitude.preemphasis,
 454                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP) |
 455                   VC4_SET_FIELD(chan2_settings->amplitude.main_driver,
 456                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV) |
 457                   VC4_SET_FIELD(clock_settings->amplitude.preemphasis,
 458                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP) |
 459                   VC4_SET_FIELD(clock_settings->amplitude.main_driver,
 460                                 VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV));
 461
 462        HDMI_WRITE(HDMI_TX_PHY_CTL_1,
 463                   HDMI_READ(HDMI_TX_PHY_CTL_1) |
 464                   VC4_SET_FIELD(chan0_settings->res_sel_data,
 465                                 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0) |
 466                   VC4_SET_FIELD(chan1_settings->res_sel_data,
 467                                 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1) |
 468                   VC4_SET_FIELD(chan2_settings->res_sel_data,
 469                                 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2) |
 470                   VC4_SET_FIELD(clock_settings->res_sel_data,
 471                                 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK));
 472
 473        HDMI_WRITE(HDMI_TX_PHY_CTL_2,
 474                   VC4_SET_FIELD(chan0_settings->term_res_sel_data,
 475                                 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0) |
 476                   VC4_SET_FIELD(chan1_settings->term_res_sel_data,
 477                                 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1) |
 478                   VC4_SET_FIELD(chan2_settings->term_res_sel_data,
 479                                 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2) |
 480                   VC4_SET_FIELD(clock_settings->term_res_sel_data,
 481                                 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK) |
 482                   VC4_SET_FIELD(phy_get_vco_gain(vco_freq),
 483                                 VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN));
 484
 485        HDMI_WRITE(HDMI_TX_PHY_CHANNEL_SWAP,
 486                   VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_0],
 487                                 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL) |
 488                   VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_1],
 489                                 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL) |
 490                   VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_2],
 491                                 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL) |
 492                   VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_CK],
 493                                 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL));
 494
 495        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
 496                   HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
 497                   ~(VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
 498                     VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB));
 499
 500        HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
 501                   HDMI_READ(HDMI_TX_PHY_RESET_CTL) |
 502                   VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
 503                   VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB);
 504}
 505
 506void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
 507{
 508        vc5_hdmi_reset_phy(vc4_hdmi);
 509}
 510
 511void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
 512{
 513        HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
 514                   HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) &
 515                   ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
 516}
 517
 518void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
 519{
 520        HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
 521                   HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) |
 522                   VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
 523}
 524