linux/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
<<
>>
Prefs
   1/*
   2 * SPDX-License-Identifier: GPL-2.0
   3 * Copyright (c) 2018, The Linux Foundation
   4 */
   5
   6#include <linux/clk.h>
   7#include <linux/clk-provider.h>
   8#include <linux/iopoll.h>
   9
  10#include "dsi_phy.h"
  11#include "dsi.xml.h"
  12#include "dsi_phy_7nm.xml.h"
  13
  14/*
  15 * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram
  16 *
  17 *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
  18 *                              |                |
  19 *                              |                |
  20 *                 +---------+  |  +----------+  |  +----+
  21 *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
  22 *                 +---------+  |  +----------+  |  +----+
  23 *                              |                |
  24 *                              |                |         dsi0_pll_by_2_bit_clk
  25 *                              |                |          |
  26 *                              |                |  +----+  |  |\  dsi0_pclk_mux
  27 *                              |                |--| /2 |--o--| \   |
  28 *                              |                |  +----+     |  \  |  +---------+
  29 *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
  30 *                              |------------------------------|  /     +---------+
  31 *                              |          +-----+             | /
  32 *                              -----------| /4? |--o----------|/
  33 *                                         +-----+  |           |
  34 *                                                  |           |dsiclk_sel
  35 *                                                  |
  36 *                                                  dsi0_pll_post_out_div_clk
  37 */
  38
  39#define VCO_REF_CLK_RATE                19200000
  40#define FRAC_BITS 18
  41
  42/* Hardware is V4.1 */
  43#define DSI_PHY_7NM_QUIRK_V4_1          BIT(0)
  44
  45struct dsi_pll_config {
  46        bool enable_ssc;
  47        bool ssc_center;
  48        u32 ssc_freq;
  49        u32 ssc_offset;
  50        u32 ssc_adj_per;
  51
  52        /* out */
  53        u32 decimal_div_start;
  54        u32 frac_div_start;
  55        u32 pll_clock_inverters;
  56        u32 ssc_stepsize;
  57        u32 ssc_div_per;
  58};
  59
  60struct pll_7nm_cached_state {
  61        unsigned long vco_rate;
  62        u8 bit_clk_div;
  63        u8 pix_clk_div;
  64        u8 pll_out_div;
  65        u8 pll_mux;
  66};
  67
  68struct dsi_pll_7nm {
  69        struct clk_hw clk_hw;
  70
  71        struct msm_dsi_phy *phy;
  72
  73        u64 vco_current_rate;
  74
  75        /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
  76        spinlock_t postdiv_lock;
  77
  78        struct pll_7nm_cached_state cached_state;
  79
  80        struct dsi_pll_7nm *slave;
  81};
  82
  83#define to_pll_7nm(x)   container_of(x, struct dsi_pll_7nm, clk_hw)
  84
  85/*
  86 * Global list of private DSI PLL struct pointers. We need this for bonded DSI
  87 * mode, where the master PLL's clk_ops needs access the slave's private data
  88 */
  89static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];
  90
  91static void dsi_pll_setup_config(struct dsi_pll_config *config)
  92{
  93        config->ssc_freq = 31500;
  94        config->ssc_offset = 4800;
  95        config->ssc_adj_per = 2;
  96
  97        /* TODO: ssc enable */
  98        config->enable_ssc = false;
  99        config->ssc_center = 0;
 100}
 101
 102static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
 103{
 104        u64 fref = VCO_REF_CLK_RATE;
 105        u64 pll_freq;
 106        u64 divider;
 107        u64 dec, dec_multiple;
 108        u32 frac;
 109        u64 multiplier;
 110
 111        pll_freq = pll->vco_current_rate;
 112
 113        divider = fref * 2;
 114
 115        multiplier = 1 << FRAC_BITS;
 116        dec_multiple = div_u64(pll_freq * multiplier, divider);
 117        div_u64_rem(dec_multiple, multiplier, &frac);
 118
 119        dec = div_u64(dec_multiple, multiplier);
 120
 121        if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
 122                config->pll_clock_inverters = 0x28;
 123        else if (pll_freq <= 1000000000ULL)
 124                config->pll_clock_inverters = 0xa0;
 125        else if (pll_freq <= 2500000000ULL)
 126                config->pll_clock_inverters = 0x20;
 127        else if (pll_freq <= 3020000000ULL)
 128                config->pll_clock_inverters = 0x00;
 129        else
 130                config->pll_clock_inverters = 0x40;
 131
 132        config->decimal_div_start = dec;
 133        config->frac_div_start = frac;
 134}
 135
 136#define SSC_CENTER              BIT(0)
 137#define SSC_EN                  BIT(1)
 138
 139static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
 140{
 141        u32 ssc_per;
 142        u32 ssc_mod;
 143        u64 ssc_step_size;
 144        u64 frac;
 145
 146        if (!config->enable_ssc) {
 147                DBG("SSC not enabled\n");
 148                return;
 149        }
 150
 151        ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
 152        ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
 153        ssc_per -= ssc_mod;
 154
 155        frac = config->frac_div_start;
 156        ssc_step_size = config->decimal_div_start;
 157        ssc_step_size *= (1 << FRAC_BITS);
 158        ssc_step_size += frac;
 159        ssc_step_size *= config->ssc_offset;
 160        ssc_step_size *= (config->ssc_adj_per + 1);
 161        ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
 162        ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
 163
 164        config->ssc_div_per = ssc_per;
 165        config->ssc_stepsize = ssc_step_size;
 166
 167        pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
 168                 config->decimal_div_start, frac, FRAC_BITS);
 169        pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
 170                 ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
 171}
 172
 173static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
 174{
 175        void __iomem *base = pll->phy->pll_base;
 176
 177        if (config->enable_ssc) {
 178                pr_debug("SSC is enabled\n");
 179
 180                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
 181                          config->ssc_stepsize & 0xff);
 182                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
 183                          config->ssc_stepsize >> 8);
 184                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1,
 185                          config->ssc_div_per & 0xff);
 186                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
 187                          config->ssc_div_per >> 8);
 188                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1,
 189                          config->ssc_adj_per & 0xff);
 190                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1,
 191                          config->ssc_adj_per >> 8);
 192                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL,
 193                          SSC_EN | (config->ssc_center ? SSC_CENTER : 0));
 194        }
 195}
 196
 197static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
 198{
 199        void __iomem *base = pll->phy->pll_base;
 200        u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
 201
 202        if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
 203                if (pll->vco_current_rate >= 3100000000ULL)
 204                        analog_controls_five_1 = 0x03;
 205
 206                if (pll->vco_current_rate < 1520000000ULL)
 207                        vco_config_1 = 0x08;
 208                else if (pll->vco_current_rate < 2990000000ULL)
 209                        vco_config_1 = 0x01;
 210        }
 211
 212        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
 213                  analog_controls_five_1);
 214        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
 215        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01);
 216        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
 217        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
 218        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00);
 219        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
 220        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
 221        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba);
 222        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
 223        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00);
 224        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00);
 225        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
 226        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a);
 227        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0);
 228        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84);
 229        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82);
 230        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c);
 231        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
 232        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29);
 233        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
 234        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
 235        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
 236                  pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22);
 237
 238        if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
 239                dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
 240                if (pll->slave)
 241                        dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
 242        }
 243}
 244
 245static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
 246{
 247        void __iomem *base = pll->phy->pll_base;
 248
 249        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
 250        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, config->decimal_div_start);
 251        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1,
 252                  config->frac_div_start & 0xff);
 253        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1,
 254                  (config->frac_div_start & 0xff00) >> 8);
 255        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
 256                  (config->frac_div_start & 0x30000) >> 16);
 257        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40);
 258        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
 259        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, pll->phy->cphy_mode ? 0x00 : 0x10);
 260        dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, config->pll_clock_inverters);
 261}
 262
 263static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
 264                                     unsigned long parent_rate)
 265{
 266        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
 267        struct dsi_pll_config config;
 268
 269        DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->phy->id, rate,
 270            parent_rate);
 271
 272        pll_7nm->vco_current_rate = rate;
 273
 274        dsi_pll_setup_config(&config);
 275
 276        dsi_pll_calc_dec_frac(pll_7nm, &config);
 277
 278        dsi_pll_calc_ssc(pll_7nm, &config);
 279
 280        dsi_pll_commit(pll_7nm, &config);
 281
 282        dsi_pll_config_hzindep_reg(pll_7nm);
 283
 284        dsi_pll_ssc_commit(pll_7nm, &config);
 285
 286        /* flush, ensure all register writes are done*/
 287        wmb();
 288
 289        return 0;
 290}
 291
 292static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)
 293{
 294        int rc;
 295        u32 status = 0;
 296        u32 const delay_us = 100;
 297        u32 const timeout_us = 5000;
 298
 299        rc = readl_poll_timeout_atomic(pll->phy->pll_base +
 300                                       REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,
 301                                       status,
 302                                       ((status & BIT(0)) > 0),
 303                                       delay_us,
 304                                       timeout_us);
 305        if (rc)
 306                pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
 307                       pll->phy->id, status);
 308
 309        return rc;
 310}
 311
 312static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)
 313{
 314        u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
 315
 316        dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0);
 317        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5));
 318        ndelay(250);
 319}
 320
 321static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
 322{
 323        u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
 324
 325        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5));
 326        dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
 327        ndelay(250);
 328}
 329
 330static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
 331{
 332        u32 data;
 333
 334        data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
 335        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5));
 336}
 337
 338static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
 339{
 340        u32 data;
 341
 342        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04);
 343
 344        data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
 345        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1,
 346                  data | BIT(5) | BIT(4));
 347}
 348
 349static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
 350{
 351        /*
 352         * Reset the PHY digital domain. This would be needed when
 353         * coming out of a CX or analog rail power collapse while
 354         * ensuring that the pads maintain LP00 or LP11 state
 355         */
 356        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
 357        wmb(); /* Ensure that the reset is deasserted */
 358        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0);
 359        wmb(); /* Ensure that the reset is deasserted */
 360}
 361
 362static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)
 363{
 364        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
 365        int rc;
 366
 367        dsi_pll_enable_pll_bias(pll_7nm);
 368        if (pll_7nm->slave)
 369                dsi_pll_enable_pll_bias(pll_7nm->slave);
 370
 371        /* Start PLL */
 372        dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01);
 373
 374        /*
 375         * ensure all PLL configurations are written prior to checking
 376         * for PLL lock.
 377         */
 378        wmb();
 379
 380        /* Check for PLL lock */
 381        rc = dsi_pll_7nm_lock_status(pll_7nm);
 382        if (rc) {
 383                pr_err("PLL(%d) lock failed\n", pll_7nm->phy->id);
 384                goto error;
 385        }
 386
 387        pll_7nm->phy->pll_on = true;
 388
 389        /*
 390         * assert power on reset for PHY digital in case the PLL is
 391         * enabled after CX of analog domain power collapse. This needs
 392         * to be done before enabling the global clk.
 393         */
 394        dsi_pll_phy_dig_reset(pll_7nm);
 395        if (pll_7nm->slave)
 396                dsi_pll_phy_dig_reset(pll_7nm->slave);
 397
 398        dsi_pll_enable_global_clk(pll_7nm);
 399        if (pll_7nm->slave)
 400                dsi_pll_enable_global_clk(pll_7nm->slave);
 401
 402error:
 403        return rc;
 404}
 405
 406static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)
 407{
 408        dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0);
 409        dsi_pll_disable_pll_bias(pll);
 410}
 411
 412static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)
 413{
 414        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
 415
 416        /*
 417         * To avoid any stray glitches while abruptly powering down the PLL
 418         * make sure to gate the clock using the clock enable bit before
 419         * powering down the PLL
 420         */
 421        dsi_pll_disable_global_clk(pll_7nm);
 422        dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0);
 423        dsi_pll_disable_sub(pll_7nm);
 424        if (pll_7nm->slave) {
 425                dsi_pll_disable_global_clk(pll_7nm->slave);
 426                dsi_pll_disable_sub(pll_7nm->slave);
 427        }
 428        /* flush, ensure all register writes are done */
 429        wmb();
 430        pll_7nm->phy->pll_on = false;
 431}
 432
 433static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
 434                                                  unsigned long parent_rate)
 435{
 436        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
 437        void __iomem *base = pll_7nm->phy->pll_base;
 438        u64 ref_clk = VCO_REF_CLK_RATE;
 439        u64 vco_rate = 0x0;
 440        u64 multiplier;
 441        u32 frac;
 442        u32 dec;
 443        u64 pll_freq, tmp64;
 444
 445        dec = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);
 446        dec &= 0xff;
 447
 448        frac = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);
 449        frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &
 450                  0xff) << 8);
 451        frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
 452                  0x3) << 16);
 453
 454        /*
 455         * TODO:
 456         *      1. Assumes prescaler is disabled
 457         */
 458        multiplier = 1 << FRAC_BITS;
 459        pll_freq = dec * (ref_clk * 2);
 460        tmp64 = (ref_clk * 2 * frac);
 461        pll_freq += div_u64(tmp64, multiplier);
 462
 463        vco_rate = pll_freq;
 464        pll_7nm->vco_current_rate = vco_rate;
 465
 466        DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
 467            pll_7nm->phy->id, (unsigned long)vco_rate, dec, frac);
 468
 469        return (unsigned long)vco_rate;
 470}
 471
 472static long dsi_pll_7nm_clk_round_rate(struct clk_hw *hw,
 473                unsigned long rate, unsigned long *parent_rate)
 474{
 475        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
 476
 477        if      (rate < pll_7nm->phy->cfg->min_pll_rate)
 478                return  pll_7nm->phy->cfg->min_pll_rate;
 479        else if (rate > pll_7nm->phy->cfg->max_pll_rate)
 480                return  pll_7nm->phy->cfg->max_pll_rate;
 481        else
 482                return rate;
 483}
 484
 485static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {
 486        .round_rate = dsi_pll_7nm_clk_round_rate,
 487        .set_rate = dsi_pll_7nm_vco_set_rate,
 488        .recalc_rate = dsi_pll_7nm_vco_recalc_rate,
 489        .prepare = dsi_pll_7nm_vco_prepare,
 490        .unprepare = dsi_pll_7nm_vco_unprepare,
 491};
 492
 493/*
 494 * PLL Callbacks
 495 */
 496
 497static void dsi_7nm_pll_save_state(struct msm_dsi_phy *phy)
 498{
 499        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
 500        struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
 501        void __iomem *phy_base = pll_7nm->phy->base;
 502        u32 cmn_clk_cfg0, cmn_clk_cfg1;
 503
 504        cached->pll_out_div = dsi_phy_read(pll_7nm->phy->pll_base +
 505                                       REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
 506        cached->pll_out_div &= 0x3;
 507
 508        cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
 509        cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
 510        cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
 511
 512        cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
 513        cached->pll_mux = cmn_clk_cfg1 & 0x3;
 514
 515        DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
 516            pll_7nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
 517            cached->pix_clk_div, cached->pll_mux);
 518}
 519
 520static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
 521{
 522        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
 523        struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
 524        void __iomem *phy_base = pll_7nm->phy->base;
 525        u32 val;
 526        int ret;
 527
 528        val = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
 529        val &= ~0x3;
 530        val |= cached->pll_out_div;
 531        dsi_phy_write(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val);
 532
 533        dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
 534                  cached->bit_clk_div | (cached->pix_clk_div << 4));
 535
 536        val = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
 537        val &= ~0x3;
 538        val |= cached->pll_mux;
 539        dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val);
 540
 541        ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw,
 542                        pll_7nm->vco_current_rate,
 543                        VCO_REF_CLK_RATE);
 544        if (ret) {
 545                DRM_DEV_ERROR(&pll_7nm->phy->pdev->dev,
 546                        "restore vco rate failed. ret=%d\n", ret);
 547                return ret;
 548        }
 549
 550        DBG("DSI PLL%d", pll_7nm->phy->id);
 551
 552        return 0;
 553}
 554
 555static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)
 556{
 557        struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
 558        void __iomem *base = phy->base;
 559        u32 data = 0x0; /* internal PLL */
 560
 561        DBG("DSI PLL%d", pll_7nm->phy->id);
 562
 563        switch (phy->usecase) {
 564        case MSM_DSI_PHY_STANDALONE:
 565                break;
 566        case MSM_DSI_PHY_MASTER:
 567                pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX];
 568                break;
 569        case MSM_DSI_PHY_SLAVE:
 570                data = 0x1; /* external PLL */
 571                break;
 572        default:
 573                return -EINVAL;
 574        }
 575
 576        /* set PLL src */
 577        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2));
 578
 579        return 0;
 580}
 581
 582/*
 583 * The post dividers and mux clocks are created using the standard divider and
 584 * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
 585 * state to follow the master PLL's divider/mux state. Therefore, we don't
 586 * require special clock ops that also configure the slave PLL registers
 587 */
 588static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provided_clocks)
 589{
 590        char clk_name[32], parent[32], vco_name[32];
 591        char parent2[32], parent3[32], parent4[32];
 592        struct clk_init_data vco_init = {
 593                .parent_names = (const char *[]){ "bi_tcxo" },
 594                .num_parents = 1,
 595                .name = vco_name,
 596                .flags = CLK_IGNORE_UNUSED,
 597                .ops = &clk_ops_dsi_pll_7nm_vco,
 598        };
 599        struct device *dev = &pll_7nm->phy->pdev->dev;
 600        struct clk_hw *hw;
 601        int ret;
 602
 603        DBG("DSI%d", pll_7nm->phy->id);
 604
 605        snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->phy->id);
 606        pll_7nm->clk_hw.init = &vco_init;
 607
 608        ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw);
 609        if (ret)
 610                return ret;
 611
 612        snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
 613        snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->phy->id);
 614
 615        hw = devm_clk_hw_register_divider(dev, clk_name,
 616                                     parent, CLK_SET_RATE_PARENT,
 617                                     pll_7nm->phy->pll_base +
 618                                     REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,
 619                                     0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
 620        if (IS_ERR(hw)) {
 621                ret = PTR_ERR(hw);
 622                goto fail;
 623        }
 624
 625        snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
 626        snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
 627
 628        /* BIT CLK: DIV_CTRL_3_0 */
 629        hw = devm_clk_hw_register_divider(dev, clk_name, parent,
 630                                     CLK_SET_RATE_PARENT,
 631                                     pll_7nm->phy->base +
 632                                     REG_DSI_7nm_PHY_CMN_CLK_CFG0,
 633                                     0, 4, CLK_DIVIDER_ONE_BASED,
 634                                     &pll_7nm->postdiv_lock);
 635        if (IS_ERR(hw)) {
 636                ret = PTR_ERR(hw);
 637                goto fail;
 638        }
 639
 640        snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id);
 641        snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
 642
 643        /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
 644        hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
 645                                          CLK_SET_RATE_PARENT, 1,
 646                                          pll_7nm->phy->cphy_mode ? 7 : 8);
 647        if (IS_ERR(hw)) {
 648                ret = PTR_ERR(hw);
 649                goto fail;
 650        }
 651
 652        provided_clocks[DSI_BYTE_PLL_CLK] = hw;
 653
 654        snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
 655        snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
 656
 657        hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent,
 658                                          0, 1, 2);
 659        if (IS_ERR(hw)) {
 660                ret = PTR_ERR(hw);
 661                goto fail;
 662        }
 663
 664        snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
 665        snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
 666
 667        if (pll_7nm->phy->cphy_mode)
 668                hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 2, 7);
 669        else
 670                hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 4);
 671        if (IS_ERR(hw)) {
 672                ret = PTR_ERR(hw);
 673                goto fail;
 674        }
 675
 676        /* in CPHY mode, pclk_mux will always have post_out_div as parent
 677         * don't register a pclk_mux clock and just use post_out_div instead
 678         */
 679        if (pll_7nm->phy->cphy_mode) {
 680                u32 data;
 681
 682                data = dsi_phy_read(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
 683                dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | 3);
 684
 685                snprintf(parent, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
 686        } else {
 687                snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);
 688                snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id);
 689                snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
 690                snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
 691                snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
 692
 693                hw = devm_clk_hw_register_mux(dev, clk_name,
 694                                        ((const char *[]){
 695                                        parent, parent2, parent3, parent4
 696                                        }), 4, 0, pll_7nm->phy->base +
 697                                        REG_DSI_7nm_PHY_CMN_CLK_CFG1,
 698                                        0, 2, 0, NULL);
 699                if (IS_ERR(hw)) {
 700                        ret = PTR_ERR(hw);
 701                        goto fail;
 702                }
 703
 704                snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->phy->id);
 705        }
 706
 707        snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id);
 708
 709        /* PIX CLK DIV : DIV_CTRL_7_4*/
 710        hw = devm_clk_hw_register_divider(dev, clk_name, parent,
 711                                     0, pll_7nm->phy->base +
 712                                        REG_DSI_7nm_PHY_CMN_CLK_CFG0,
 713                                     4, 4, CLK_DIVIDER_ONE_BASED,
 714                                     &pll_7nm->postdiv_lock);
 715        if (IS_ERR(hw)) {
 716                ret = PTR_ERR(hw);
 717                goto fail;
 718        }
 719
 720        provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
 721
 722        return 0;
 723
 724fail:
 725
 726        return ret;
 727}
 728
 729static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)
 730{
 731        struct platform_device *pdev = phy->pdev;
 732        struct dsi_pll_7nm *pll_7nm;
 733        int ret;
 734
 735        pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);
 736        if (!pll_7nm)
 737                return -ENOMEM;
 738
 739        DBG("DSI PLL%d", phy->id);
 740
 741        pll_7nm_list[phy->id] = pll_7nm;
 742
 743        spin_lock_init(&pll_7nm->postdiv_lock);
 744
 745        pll_7nm->phy = phy;
 746
 747        ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
 748        if (ret) {
 749                DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
 750                return ret;
 751        }
 752
 753        phy->vco_hw = &pll_7nm->clk_hw;
 754
 755        /* TODO: Remove this when we have proper display handover support */
 756        msm_dsi_phy_pll_save_state(phy);
 757
 758        return 0;
 759}
 760
 761static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy)
 762{
 763        void __iomem *base = phy->base;
 764        u32 data = 0;
 765
 766        data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);
 767        mb(); /* make sure read happened */
 768
 769        return (data & BIT(0));
 770}
 771
 772static void dsi_phy_hw_v4_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
 773{
 774        void __iomem *lane_base = phy->lane_base;
 775        int phy_lane_0 = 0;     /* TODO: Support all lane swap configs */
 776
 777        /*
 778         * LPRX and CDRX need to enabled only for physical data lane
 779         * corresponding to the logical data lane 0
 780         */
 781        if (enable)
 782                dsi_phy_write(lane_base +
 783                              REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3);
 784        else
 785                dsi_phy_write(lane_base +
 786                              REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0);
 787}
 788
 789static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)
 790{
 791        int i;
 792        const u8 tx_dctrl_0[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
 793        const u8 tx_dctrl_1[] = { 0x40, 0x40, 0x40, 0x46, 0x41 };
 794        const u8 *tx_dctrl = tx_dctrl_0;
 795        void __iomem *lane_base = phy->lane_base;
 796
 797        if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)
 798                tx_dctrl = tx_dctrl_1;
 799
 800        /* Strength ctrl settings */
 801        for (i = 0; i < 5; i++) {
 802                /*
 803                 * Disable LPRX and CDRX for all lanes. And later on, it will
 804                 * be only enabled for the physical data lane corresponding
 805                 * to the logical data lane 0
 806                 */
 807                dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i), 0);
 808                dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i), 0x0);
 809        }
 810
 811        dsi_phy_hw_v4_0_config_lpcdrx(phy, true);
 812
 813        /* other settings */
 814        for (i = 0; i < 5; i++) {
 815                dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG0(i), 0x0);
 816                dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG1(i), 0x0);
 817                dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG2(i), i == 4 ? 0x8a : 0xa);
 818                dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]);
 819        }
 820}
 821
 822static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
 823                              struct msm_dsi_phy_clk_request *clk_req)
 824{
 825        int ret;
 826        u32 status;
 827        u32 const delay_us = 5;
 828        u32 const timeout_us = 1000;
 829        struct msm_dsi_dphy_timing *timing = &phy->timing;
 830        void __iomem *base = phy->base;
 831        bool less_than_1500_mhz;
 832        u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
 833        u32 glbl_pemph_ctrl_0;
 834        u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;
 835        u32 glbl_rescode_top_ctrl, glbl_rescode_bot_ctrl;
 836        u32 data;
 837
 838        DBG("");
 839
 840        if (phy->cphy_mode)
 841                ret = msm_dsi_cphy_timing_calc_v4(timing, clk_req);
 842        else
 843                ret = msm_dsi_dphy_timing_calc_v4(timing, clk_req);
 844        if (ret) {
 845                DRM_DEV_ERROR(&phy->pdev->dev,
 846                        "%s: PHY timing calculation failed\n", __func__);
 847                return -EINVAL;
 848        }
 849
 850        if (dsi_phy_hw_v4_0_is_pll_on(phy))
 851                pr_warn("PLL turned on before configuring PHY\n");
 852
 853        /* wait for REFGEN READY */
 854        ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,
 855                                        status, (status & BIT(0)),
 856                                        delay_us, timeout_us);
 857        if (ret) {
 858                pr_err("Ref gen not ready. Aborting\n");
 859                return -EINVAL;
 860        }
 861
 862        /* TODO: CPHY enable path (this is for DPHY only) */
 863
 864        /* Alter PHY configurations if data rate less than 1.5GHZ*/
 865        less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);
 866
 867        /* For C-PHY, no low power settings for lower clk rate */
 868        if (phy->cphy_mode)
 869                less_than_1500_mhz = false;
 870
 871        if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
 872                vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
 873                glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x00;
 874                glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 :  0x3c;
 875                glbl_str_swi_cal_sel_ctrl = 0x00;
 876                glbl_hstx_str_ctrl_0 = 0x88;
 877        } else {
 878                vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
 879                glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
 880                glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;
 881                glbl_rescode_top_ctrl = 0x03;
 882                glbl_rescode_bot_ctrl = 0x3c;
 883        }
 884
 885        if (phy->cphy_mode) {
 886                vreg_ctrl_0 = 0x51;
 887                vreg_ctrl_1 = 0x55;
 888                glbl_pemph_ctrl_0 = 0x11;
 889                lane_ctrl0 = 0x17;
 890        } else {
 891                vreg_ctrl_1 = 0x5c;
 892                glbl_pemph_ctrl_0 = 0x00;
 893                lane_ctrl0 = 0x1f;
 894        }
 895
 896        /* de-assert digital and pll power down */
 897        data = BIT(6) | BIT(5);
 898        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
 899
 900        /* Assert PLL core reset */
 901        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x00);
 902
 903        /* turn off resync FIFO */
 904        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00);
 905
 906        /* program CMN_CTRL_4 for minor_ver 2 chipsets*/
 907        data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0);
 908        data = data & (0xf0);
 909        if (data == 0x20)
 910                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04);
 911
 912        /* Configure PHY lane swap (TODO: we need to calculate this) */
 913        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG0, 0x21);
 914        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG1, 0x84);
 915
 916        if (phy->cphy_mode)
 917                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL, BIT(6));
 918
 919        /* Enable LDO */
 920        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0, vreg_ctrl_0);
 921        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, vreg_ctrl_1);
 922
 923        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x00);
 924        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL,
 925                      glbl_str_swi_cal_sel_ctrl);
 926        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0,
 927                      glbl_hstx_str_ctrl_0);
 928        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0,
 929                      glbl_pemph_ctrl_0);
 930        if (phy->cphy_mode)
 931                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1, 0x01);
 932        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL,
 933                      glbl_rescode_top_ctrl);
 934        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL,
 935                      glbl_rescode_bot_ctrl);
 936        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
 937
 938        /* Remove power down from all blocks */
 939        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x7f);
 940
 941        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, lane_ctrl0);
 942
 943        /* Select full-rate mode */
 944        if (!phy->cphy_mode)
 945                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40);
 946
 947        ret = dsi_7nm_set_usecase(phy);
 948        if (ret) {
 949                DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
 950                        __func__, ret);
 951                return ret;
 952        }
 953
 954        /* DSI PHY timings */
 955        if (phy->cphy_mode) {
 956                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
 957                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
 958                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5,
 959                        timing->shared_timings.clk_pre);
 960                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->clk_prepare);
 961                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7,
 962                        timing->shared_timings.clk_post);
 963                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
 964                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
 965                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
 966                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
 967        } else {
 968                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
 969                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero);
 970                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare);
 971                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail);
 972                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
 973                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero);
 974                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare);
 975                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail);
 976                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
 977                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
 978                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
 979                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
 980                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12,
 981                        timing->shared_timings.clk_pre);
 982                dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13,
 983                        timing->shared_timings.clk_post);
 984        }
 985
 986        /* DSI lane settings */
 987        dsi_phy_hw_v4_0_lane_settings(phy);
 988
 989        DBG("DSI%d PHY enabled", phy->id);
 990
 991        return 0;
 992}
 993
 994static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)
 995{
 996        void __iomem *base = phy->base;
 997        u32 data;
 998
 999        data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1);
1000        if (enable)
1001                data |= BIT(5) | BIT(6);
1002        else
1003                data &= ~(BIT(5) | BIT(6));
1004        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1, data);
1005
1006        return enable;
1007}
1008
1009static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
1010{
1011        void __iomem *base = phy->base;
1012        u32 data;
1013
1014        DBG("");
1015
1016        if (dsi_phy_hw_v4_0_is_pll_on(phy))
1017                pr_warn("Turning OFF PHY while PLL is on\n");
1018
1019        dsi_phy_hw_v4_0_config_lpcdrx(phy, false);
1020        data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_CTRL_0);
1021
1022        /* disable all lanes */
1023        data &= ~0x1F;
1024        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
1025        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, 0);
1026
1027        /* Turn off all PHY blocks */
1028        dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x00);
1029        /* make sure phy is turned off */
1030        wmb();
1031
1032        DBG("DSI%d PHY disabled", phy->id);
1033}
1034
1035const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
1036        .has_phy_lane = true,
1037        .reg_cfg = {
1038                .num = 1,
1039                .regs = {
1040                        {"vdds", 36000, 32},
1041                },
1042        },
1043        .ops = {
1044                .enable = dsi_7nm_phy_enable,
1045                .disable = dsi_7nm_phy_disable,
1046                .pll_init = dsi_pll_7nm_init,
1047                .save_pll_state = dsi_7nm_pll_save_state,
1048                .restore_pll_state = dsi_7nm_pll_restore_state,
1049                .set_continuous_clock = dsi_7nm_set_continuous_clock,
1050        },
1051        .min_pll_rate = 600000000UL,
1052#ifdef CONFIG_64BIT
1053        .max_pll_rate = 5000000000UL,
1054#else
1055        .max_pll_rate = ULONG_MAX,
1056#endif
1057        .io_start = { 0xae94400, 0xae96400 },
1058        .num_dsi_phy = 2,
1059        .quirks = DSI_PHY_7NM_QUIRK_V4_1,
1060};
1061
1062const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
1063        .has_phy_lane = true,
1064        .reg_cfg = {
1065                .num = 1,
1066                .regs = {
1067                        {"vdds", 36000, 32},
1068                },
1069        },
1070        .ops = {
1071                .enable = dsi_7nm_phy_enable,
1072                .disable = dsi_7nm_phy_disable,
1073                .pll_init = dsi_pll_7nm_init,
1074                .save_pll_state = dsi_7nm_pll_save_state,
1075                .restore_pll_state = dsi_7nm_pll_restore_state,
1076                .set_continuous_clock = dsi_7nm_set_continuous_clock,
1077        },
1078        .min_pll_rate = 1000000000UL,
1079        .max_pll_rate = 3500000000UL,
1080        .io_start = { 0xae94400, 0xae96400 },
1081        .num_dsi_phy = 2,
1082};
1083
1084const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
1085        .has_phy_lane = true,
1086        .reg_cfg = {
1087                .num = 1,
1088                .regs = {
1089                        {"vdds", 37550, 0},
1090                },
1091        },
1092        .ops = {
1093                .enable = dsi_7nm_phy_enable,
1094                .disable = dsi_7nm_phy_disable,
1095                .pll_init = dsi_pll_7nm_init,
1096                .save_pll_state = dsi_7nm_pll_save_state,
1097                .restore_pll_state = dsi_7nm_pll_restore_state,
1098        },
1099        .min_pll_rate = 600000000UL,
1100#ifdef CONFIG_64BIT
1101        .max_pll_rate = 5000000000ULL,
1102#else
1103        .max_pll_rate = ULONG_MAX,
1104#endif
1105        .io_start = { 0xae94400 },
1106        .num_dsi_phy = 1,
1107        .quirks = DSI_PHY_7NM_QUIRK_V4_1,
1108};
1109