FILE
dsi_phy_28nm_8960.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. 4 */ 5 6#include <dt-bindings/clock/qcom,dsi-phy-28nm.h> 7#include <linux/clk-provider.h> 8#include <linux/delay.h> 9 10#include "dsi_phy.h" 11#include "dsi.xml.h" 12#include "dsi_phy_28nm_8960.xml.h" 13 14/* 15 * DSI PLL 28nm (8960/A family) - clock diagram (eg: DSI1): 16 * 17 * 18 * +------+ 19 * dsi1vco_clk ----o-----| DIV1 |---dsi1pllbit (not exposed as clock) 20 * F * byte_clk | +------+ 21 * | bit clock divider (F / 8) 22 * | 23 * | +------+ 24 * o-----| DIV2 |---dsi0pllbyte---o---> To byte RCG 25 * | +------+ | (sets parent rate) 26 * | byte clock divider (F) | 27 * | | 28 * | o---> To esc RCG 29 * | (doesn't set parent rate) 30 * | 31 * | +------+ 32 * o-----| DIV3 |----dsi0pll------o---> To dsi RCG 33 * +------+ | (sets parent rate) 34 * dsi clock divider (F * magic) | 35 * | 36 * o---> To pixel rcg 37 * (doesn't set parent rate) 38 */ 39 40#define POLL_MAX_READS 8000 41#define POLL_TIMEOUT_US 1 42 43#define VCO_REF_CLK_RATE 27000000 44#define VCO_MIN_RATE 600000000 45#define VCO_MAX_RATE 1200000000 46 47#define VCO_PREF_DIV_RATIO 27 48 49struct pll_28nm_cached_state { 50 unsigned long vco_rate; 51 u8 postdiv3; 52 u8 postdiv2; 53 u8 postdiv1; 54}; 55 56struct clk_bytediv { 57 struct clk_hw hw; 58 void __iomem *reg; 59}; 60 61struct dsi_pll_28nm { 62 struct clk_hw clk_hw; 63 64 struct msm_dsi_phy *phy; 65 66 struct pll_28nm_cached_state cached_state; 67}; 68 69#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, clk_hw) 70 71static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, 72 int nb_tries, int timeout_us) 73{ 74 bool pll_locked = false; 75 u32 val; 76 77 while (nb_tries--) { 78 val = readl(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_RDY); 79 pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY); 80 81 if (pll_locked) 82 break; 83 84 udelay(timeout_us); 85 } 86 DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); 87 88 return pll_locked; 89} 90 91/* 92 * Clock Callbacks 93 */ 94static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, 95 unsigned long parent_rate) 96{ 97 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); 98 void __iomem *base = pll_28nm->phy->pll_base; 99 u32 val, temp, fb_divider; 100 101 DBG("rate=%lu, parent's=%lu", rate, parent_rate); 102 103 temp = rate / 10; 104 val = VCO_REF_CLK_RATE / 10; 105 fb_divider = (temp * VCO_PREF_DIV_RATIO) / val; 106 fb_divider = fb_divider / 2 - 1; 107 writel(fb_divider & 0xff, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); 108 109 val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); 110 111 val |= (fb_divider >> 8) & 0x07; 112 113 writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); 114 115 val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); 116 117 val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f; 118 119 writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); 120 121 writel(0xf, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6); 122 123 val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); 124 val |= 0x7 << 4; 125 writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); 126 127 return 0; 128} 129 130static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) 131{ 132 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); 133 134 return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, 135 POLL_TIMEOUT_US); 136} 137 138static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, 139 unsigned long parent_rate) 140{ 141 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); 142 void __iomem *base = pll_28nm->phy->pll_base; 143 unsigned long vco_rate; 144 u32 status, fb_divider, temp, ref_divider; 145 146 VERB("parent_rate=%lu", parent_rate); 147 148 status = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); 149 150 if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) { 151 fb_divider = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); 152 fb_divider &= 0xff; 153 temp = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07; 154 fb_divider = (temp << 8) | fb_divider; 155 fb_divider += 1; 156 157 ref_divider = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); 158 ref_divider &= 0x3f; 159 ref_divider += 1; 160 161 /* multiply by 2 */ 162 vco_rate = (parent_rate / ref_divider) * fb_divider * 2; 163 } else { 164 vco_rate = 0; 165 } 166 167 DBG("returning vco rate = %lu", vco_rate); 168 169 return vco_rate; 170} 171 172static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) 173{ 174 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); 175 struct device *dev = &pll_28nm->phy->pdev->dev; 176 void __iomem *base = pll_28nm->phy->pll_base; 177 bool locked; 178 unsigned int bit_div, byte_div; 179 int max_reads = 1000, timeout_us = 100; 180 u32 val; 181 182 DBG("id=%d", pll_28nm->phy->id); 183 184 if (unlikely(pll_28nm->phy->pll_on)) 185 return 0; 186 187 /* 188 * before enabling the PLL, configure the bit clock divider since we 189 * don't expose it as a clock to the outside world 190 * 1: read back the byte clock divider that should already be set 191 * 2: divide by 8 to get bit clock divider 192 * 3: write it to POSTDIV1 193 */ 194 val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); 195 byte_div = val + 1; 196 bit_div = byte_div / 8; 197 198 val = readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); 199 val &= ~0xf; 200 val |= (bit_div - 1); 201 writel(val, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); 202 203 /* enable the PLL */ 204 writel(DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE, 205 base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); 206 207 locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); 208 209 if (unlikely(!locked)) { 210 DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); 211 return -EINVAL; 212 } 213 214 DBG("DSI PLL lock success"); 215 pll_28nm->phy->pll_on = true; 216 217 return 0; 218} 219 220static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) 221{ 222 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); 223 224 DBG("id=%d", pll_28nm->phy->id); 225 226 if (unlikely(!pll_28nm->phy->pll_on)) 227 return; 228 229 writel(0x00, pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); 230 231 pll_28nm->phy->pll_on = false; 232} 233 234static int dsi_pll_28nm_clk_determine_rate(struct clk_hw *hw, 235 struct clk_rate_request *req) 236{ 237 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); 238 239 req->rate = clamp_t(unsigned long, req->rate, 240 pll_28nm->phy->cfg->min_pll_rate, pll_28nm->phy->cfg->max_pll_rate); 241 242 return 0; 243} 244 245static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { 246 .determine_rate = dsi_pll_28nm_clk_determine_rate, 247 .set_rate = dsi_pll_28nm_clk_set_rate, 248 .recalc_rate = dsi_pll_28nm_clk_recalc_rate, 249 .prepare = dsi_pll_28nm_vco_prepare, 250 .unprepare = dsi_pll_28nm_vco_unprepare, 251 .is_enabled = dsi_pll_28nm_clk_is_enabled, 252}; 253 254/* 255 * Custom byte clock divier clk_ops 256 * 257 * This clock is the entry point to configuring the PLL. The user (dsi host) 258 * will set this clock's rate to the desired byte clock rate. The VCO lock 259 * frequency is a multiple of the byte clock rate. The multiplication factor 260 * (shown as F in the diagram above) is a function of the byte clock rate. 261 * 262 * This custom divider clock ensures that its parent (VCO) is set to the 263 * desired rate, and that the byte clock postdivider (POSTDIV2) is configured 264 * accordingly 265 */ 266#define to_clk_bytediv(_hw) container_of(_hw, struct clk_bytediv, hw) 267 268static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw, 269 unsigned long parent_rate) 270{ 271 struct clk_bytediv *bytediv = to_clk_bytediv(hw); 272 unsigned int div; 273 274 div = readl(bytediv->reg) & 0xff; 275 276 return parent_rate / (div + 1); 277} 278 279/* find multiplication factor(wrt byte clock) at which the VCO should be set */ 280static unsigned int get_vco_mul_factor(unsigned long byte_clk_rate) 281{ 282 unsigned long bit_mhz; 283 284 /* convert to bit clock in Mhz */ 285 bit_mhz = (byte_clk_rate * 8) / 1000000; 286 287 if (bit_mhz < 125) 288 return 64; 289 else if (bit_mhz < 250) 290 return 32; 291 else if (bit_mhz < 600) 292 return 16; 293 else 294 return 8; 295} 296 297static int clk_bytediv_determine_rate(struct clk_hw *hw, 298 struct clk_rate_request *req) 299{ 300 unsigned long best_parent; 301 unsigned int factor; 302 303 factor = get_vco_mul_factor(req->rate); 304 305 best_parent = req->rate * factor; 306 req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); 307 308 req->rate = req->best_parent_rate / factor; 309 310 return 0; 311} 312 313static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate, 314 unsigned long parent_rate) 315{ 316 struct clk_bytediv *bytediv = to_clk_bytediv(hw); 317 u32 val; 318 unsigned int factor; 319 320 factor = get_vco_mul_factor(rate); 321 322 val = readl(bytediv->reg); 323 val |= (factor - 1) & 0xff; 324 writel(val, bytediv->reg); 325 326 return 0; 327} 328 329/* Our special byte clock divider ops */ 330static const struct clk_ops clk_bytediv_ops = { 331 .determine_rate = clk_bytediv_determine_rate, 332 .set_rate = clk_bytediv_set_rate, 333 .recalc_rate = clk_bytediv_recalc_rate, 334}; 335 336/* 337 * PLL Callbacks 338 */ 339static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy) 340{ 341 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); 342 struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; 343 void __iomem *base = pll_28nm->phy->pll_base; 344 345 cached_state->postdiv3 = 346 readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); 347 cached_state->postdiv2 = 348 readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); 349 cached_state->postdiv1 = 350 readl(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); 351 352 cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); 353} 354 355static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy) 356{ 357 struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); 358 struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; 359 void __iomem *base = pll_28nm->phy->pll_base; 360 int ret; 361 362 ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, 363 cached_state->vco_rate, 0); 364 if (ret) { 365 DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev, 366 "restore vco rate failed. ret=%d\n", ret); 367 return ret; 368 } 369 370 writel(cached_state->postdiv3, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); 371 writel(cached_state->postdiv2, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); 372 writel(cached_state->postdiv1, base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); 373 374 return 0; 375} 376 377static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks) 378{ 379 char clk_name[32]; 380 struct clk_init_data vco_init = { 381 .parent_data = &(const struct clk_parent_data) { 382 .fw_name = "ref", 383 }, 384 .num_parents = 1, 385 .flags = CLK_IGNORE_UNUSED, 386 .ops = &clk_ops_dsi_pll_28nm_vco, 387 }; 388 struct device *dev = &pll_28nm->phy->pdev->dev; 389 struct clk_hw *hw; 390 struct clk_bytediv *bytediv; 391 struct clk_init_data bytediv_init = { }; 392 int ret; 393 394 DBG("%d", pll_28nm->phy->id); 395 396 bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL); 397 if (!bytediv) 398 return -ENOMEM; 399 400 snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_28nm->phy->id); 401 vco_init.name = clk_name; 402 403 pll_28nm->clk_hw.init = &vco_init; 404 405 ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw); 406 if (ret) 407 return ret; 408 409 /* prepare and register bytediv */ 410 bytediv->hw.init = &bytediv_init; 411 bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; 412 413 snprintf(clk_name, sizeof(clk_name), "dsi%dpllbyte", pll_28nm->phy->id + 1); 414 415 bytediv_init.name = clk_name; 416 bytediv_init.ops = &clk_bytediv_ops; 417 bytediv_init.flags = CLK_SET_RATE_PARENT; 418 bytediv_init.parent_hws = (const struct clk_hw*[]){ 419 &pll_28nm->clk_hw, 420 }; 421 bytediv_init.num_parents = 1; 422 423 /* DIV2 */ 424 ret = devm_clk_hw_register(dev, &bytediv->hw); 425 if (ret) 426 return ret; 427 provided_clocks[DSI_BYTE_PLL_CLK] = &bytediv->hw; 428 429 snprintf(clk_name, sizeof(clk_name), "dsi%dpll", pll_28nm->phy->id + 1); 430 /* DIV3 */ 431 hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, 432 &pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base + 433 REG_DSI_28nm_8960_PHY_PLL_CTRL_10, 434 0, 8, 0, NULL); 435 if (IS_ERR(hw)) 436 return PTR_ERR(hw); 437 provided_clocks[DSI_PIXEL_PLL_CLK] = hw; 438 439 return 0; 440} 441 442static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) 443{ 444 struct platform_device *pdev = phy->pdev; 445 struct dsi_pll_28nm *pll_28nm; 446 int ret; 447 448 if (!pdev) 449 return -ENODEV; 450 451 pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL); 452 if (!pll_28nm) 453 return -ENOMEM; 454 455 pll_28nm->phy = phy; 456 457 ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); 458 if (ret) { 459 DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); 460 return ret; 461 } 462 463 phy->vco_hw = &pll_28nm->clk_hw; 464 465 return 0; 466} 467 468static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy, 469 struct msm_dsi_dphy_timing *timing) 470{ 471 void __iomem *base = phy->base; 472 473 writel(DSI_28nm_8960_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero), 474 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_0); 475 writel(DSI_28nm_8960_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail), 476 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_1); 477 writel(DSI_28nm_8960_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare), 478 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_2); 479 writel(0, base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_3); 480 writel(DSI_28nm_8960_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit), 481 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_4); 482 writel(DSI_28nm_8960_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero), 483 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_5); 484 writel(DSI_28nm_8960_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare), 485 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_6); 486 writel(DSI_28nm_8960_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail), 487 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_7); 488 writel(DSI_28nm_8960_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst), 489 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_8); 490 writel(DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) | 491 DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure), 492 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_9); 493 writel(DSI_28nm_8960_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get), 494 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_10); 495 writel(DSI_28nm_8960_PHY_TIMING_CTRL_11_TRIG3_CMD(0), 496 base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_11); 497} 498 499static void dsi_28nm_phy_regulator_init(struct msm_dsi_phy *phy) 500{ 501 void __iomem *base = phy->reg_base; 502 503 writel(0x3, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0); 504 writel(1, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1); 505 writel(1, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2); 506 writel(0, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3); 507 writel(0x100, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4); 508} 509 510static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy) 511{ 512 void __iomem *base = phy->reg_base; 513 514 writel(0x3, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0); 515 writel(0xa, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1); 516 writel(0x4, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2); 517 writel(0x0, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3); 518 writel(0x20, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4); 519} 520 521static void dsi_28nm_phy_calibration(struct msm_dsi_phy *phy) 522{ 523 void __iomem *base = phy->reg_base; 524 u32 status; 525 int i = 5000; 526 527 writel(0x3, base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CAL_PWR_CFG); 528 529 writel(0x0, base + REG_DSI_28nm_8960_PHY_MISC_CAL_SW_CFG_2); 530 writel(0x5a, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_1); 531 writel(0x10, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_3); 532 writel(0x1, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_4); 533 writel(0x1, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_0); 534 535 writel(0x1, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER); 536 usleep_range(5000, 6000); 537 writel(0x0, base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER); 538 539 do { 540 status = readl(base + 541 REG_DSI_28nm_8960_PHY_MISC_CAL_STATUS); 542 543 if (!(status & DSI_28nm_8960_PHY_MISC_CAL_STATUS_CAL_BUSY)) 544 break; 545 546 udelay(1); 547 } while (--i > 0); 548} 549 550static void dsi_28nm_phy_lane_config(struct msm_dsi_phy *phy) 551{ 552 void __iomem *base = phy->base; 553 int i; 554 555 for (i = 0; i < 4; i++) { 556 writel(0x80, base + REG_DSI_28nm_8960_PHY_LN_CFG_0(i)); 557 writel(0x45, base + REG_DSI_28nm_8960_PHY_LN_CFG_1(i)); 558 writel(0x00, base + REG_DSI_28nm_8960_PHY_LN_CFG_2(i)); 559 writel(0x00, base + REG_DSI_28nm_8960_PHY_LN_TEST_DATAPATH(i)); 560 writel(0x01, base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_0(i)); 561 writel(0x66, base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_1(i)); 562 } 563 564 writel(0x40, base + REG_DSI_28nm_8960_PHY_LNCK_CFG_0); 565 writel(0x67, base + REG_DSI_28nm_8960_PHY_LNCK_CFG_1); 566 writel(0x0, base + REG_DSI_28nm_8960_PHY_LNCK_CFG_2); 567 writel(0x0, base + REG_DSI_28nm_8960_PHY_LNCK_TEST_DATAPATH); 568 writel(0x1, base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR0); 569 writel(0x88, base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1); 570} 571 572static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, 573 struct msm_dsi_phy_clk_request *clk_req) 574{ 575 struct msm_dsi_dphy_timing *timing = &phy->timing; 576 void __iomem *base = phy->base; 577 578 DBG(""); 579 580 if (msm_dsi_dphy_timing_calc(timing, clk_req)) { 581 DRM_DEV_ERROR(&phy->pdev->dev, 582 "%s: D-PHY timing calculation failed\n", 583 __func__); 584 return -EINVAL; 585 } 586 587 dsi_28nm_phy_regulator_init(phy); 588 589 writel(0x04, base + REG_DSI_28nm_8960_PHY_LDO_CTRL); 590 591 /* strength control */ 592 writel(0xff, base + REG_DSI_28nm_8960_PHY_STRENGTH_0); 593 writel(0x00, base + REG_DSI_28nm_8960_PHY_STRENGTH_1); 594 writel(0x06, base + REG_DSI_28nm_8960_PHY_STRENGTH_2); 595 596 /* phy ctrl */ 597 writel(0x5f, base + REG_DSI_28nm_8960_PHY_CTRL_0); 598 writel(0x00, base + REG_DSI_28nm_8960_PHY_CTRL_1); 599 writel(0x00, base + REG_DSI_28nm_8960_PHY_CTRL_2); 600 writel(0x10, base + REG_DSI_28nm_8960_PHY_CTRL_3); 601 602 dsi_28nm_phy_regulator_ctrl(phy); 603 604 dsi_28nm_phy_calibration(phy); 605 606 dsi_28nm_phy_lane_config(phy); 607 608 writel(0x0f, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4); 609 writel(0x03, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_1); 610 writel(0x03, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_0); 611 writel(0x0, base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4); 612 613 dsi_28nm_dphy_set_timing(phy, timing); 614 615 return 0; 616} 617 618static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy) 619{ 620 writel(0x0, phy->base + REG_DSI_28nm_8960_PHY_CTRL_0); 621 622 /* 623 * Wait for the registers writes to complete in order to 624 * ensure that the phy is completely disabled 625 */ 626 wmb(); 627} 628 629static const struct regulator_bulk_data dsi_phy_28nm_8960_regulators[] = { 630 { .supply = "vddio", .init_load_uA = 100000 }, /* 1.8 V */ 631}; 632 633const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = { 634 .has_phy_regulator = true, 635 .regulator_data = dsi_phy_28nm_8960_regulators, 636 .num_regulators = ARRAY_SIZE(dsi_phy_28nm_8960_regulators), 637 .ops = { 638 .enable = dsi_28nm_phy_enable, 639 .disable = dsi_28nm_phy_disable, 640 .pll_init = dsi_pll_28nm_8960_init, 641 .save_pll_state = dsi_28nm_pll_save_state, 642 .restore_pll_state = dsi_28nm_pll_restore_state, 643 }, 644 .min_pll_rate = VCO_MIN_RATE, 645 .max_pll_rate = VCO_MAX_RATE, 646 .io_start = { 0x4700300, 0x5800300 }, 647 .num_dsi_phy = 2, 648};
~/
Read-only file preview.