1 /* 2 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <config.h> 8 #include <common.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <asm/unaligned.h> 12 #include <asm/io.h> 13 #include <linux/list.h> 14 #include <div64.h> 15 #include <dm/device.h> 16 #include <dm/read.h> 17 #include <dm/uclass.h> 18 #include <dm/uclass-id.h> 19 20 #include "rockchip_phy.h" 21 22 #define NSEC_PER_USEC 1000L 23 #define USEC_PER_SEC 1000000L 24 #define NSEC_PER_SEC 1000000000L 25 26 #define UPDATE(v, h, l) (((v) << (l)) & GENMASK((h), (l))) 27 28 /* Innosilicon MIPI D-PHY registers */ 29 #define INNO_PHY_LANE_CTRL 0x00000 30 #define MIPI_BGPD BIT(7) 31 #define CLK_LANE_EN_MASK BIT(6) 32 #define DATA_LANE_3_EN_MASK BIT(5) 33 #define DATA_LANE_2_EN_MASK BIT(4) 34 #define DATA_LANE_1_EN_MASK BIT(3) 35 #define DATA_LANE_0_EN_MASK BIT(2) 36 #define CLK_LANE_EN BIT(6) 37 #define DATA_LANE_3_EN BIT(5) 38 #define DATA_LANE_2_EN BIT(4) 39 #define DATA_LANE_1_EN BIT(3) 40 #define DATA_LANE_0_EN BIT(2) 41 #define PWROK_BP BIT(1) 42 #define PWROK BIT(0) 43 #define INNO_PHY_POWER_CTRL 0x00004 44 #define ANALOG_RESET_MASK BIT(2) 45 #define ANALOG_RESET BIT(2) 46 #define ANALOG_NORMAL 0 47 #define LDO_POWER_MASK BIT(1) 48 #define LDO_POWER_DOWN BIT(1) 49 #define LDO_POWER_ON 0 50 #define PLL_POWER_MASK BIT(0) 51 #define PLL_POWER_DOWN BIT(0) 52 #define PLL_POWER_ON 0 53 #define INNO_PHY_PLL_CTRL_0 0x0000c 54 #define FBDIV_HI_MASK BIT(5) 55 #define FBDIV_HI(x) UPDATE(x, 5, 5) 56 #define PREDIV_MASK GENMASK(4, 0) 57 #define PREDIV(x) UPDATE(x, 4, 0) 58 #define INNO_PHY_PLL_CTRL_1 0x00010 59 #define FBDIV_LO_MASK GENMASK(7, 0) 60 #define FBDIV_LO(x) UPDATE(x, 7, 0) 61 #define INNO_PHY_DIG_CTRL 0x00080 62 #define DIGITAL_RESET_MASK BIT(0) 63 #define DIGITAL_NORMAL BIT(0) 64 #define DIGITAL_RESET 0 65 #define INNO_PHY_LVDS_CTRL 0x003ac 66 #define LVDS_BGPD BIT(0) 67 68 #define INNO_CLOCK_LANE_REG_BASE 0x00100 69 #define INNO_DATA_LANE_0_REG_BASE 0x00180 70 #define INNO_DATA_LANE_1_REG_BASE 0x00200 71 #define INNO_DATA_LANE_2_REG_BASE 0x00280 72 #define INNO_DATA_LANE_3_REG_BASE 0x00300 73 74 #define T_LPX_OFFSET 0x00014 75 #define T_HS_PREPARE_OFFSET 0x00018 76 #define T_HS_ZERO_OFFSET 0x0001c 77 #define T_HS_TRAIL_OFFSET 0x00020 78 #define T_HS_EXIT_OFFSET 0x00024 79 #define T_CLK_POST_OFFSET 0x00028 80 #define T_WAKUP_H_OFFSET 0x00030 81 #define T_WAKUP_L_OFFSET 0x00034 82 #define T_CLK_PRE_OFFSET 0x00038 83 #define T_TA_GO_OFFSET 0x00040 84 #define T_TA_SURE_OFFSET 0x00044 85 #define T_TA_WAIT_OFFSET 0x00048 86 87 #define T_LPX_MASK GENMASK(5, 0) 88 #define T_LPX(x) UPDATE(x, 5, 0) 89 #define T_HS_PREPARE_MASK GENMASK(6, 0) 90 #define T_HS_PREPARE(x) UPDATE(x, 6, 0) 91 #define T_HS_ZERO_MASK GENMASK(5, 0) 92 #define T_HS_ZERO(x) UPDATE(x, 5, 0) 93 #define T_HS_TRAIL_MASK GENMASK(6, 0) 94 #define T_HS_TRAIL(x) UPDATE(x, 6, 0) 95 #define T_HS_EXIT_MASK GENMASK(4, 0) 96 #define T_HS_EXIT(x) UPDATE(x, 4, 0) 97 #define T_CLK_POST_MASK GENMASK(3, 0) 98 #define T_CLK_POST(x) UPDATE(x, 3, 0) 99 #define T_WAKUP_H_MASK GENMASK(1, 0) 100 #define T_WAKUP_H(x) UPDATE(x, 1, 0) 101 #define T_WAKUP_L_MASK GENMASK(7, 0) 102 #define T_WAKUP_L(x) UPDATE(x, 7, 0) 103 #define T_CLK_PRE_MASK GENMASK(3, 0) 104 #define T_CLK_PRE(x) UPDATE(x, 3, 0) 105 #define T_TA_GO_MASK GENMASK(5, 0) 106 #define T_TA_GO(x) UPDATE(x, 5, 0) 107 #define T_TA_SURE_MASK GENMASK(5, 0) 108 #define T_TA_SURE(x) UPDATE(x, 5, 0) 109 #define T_TA_WAIT_MASK GENMASK(5, 0) 110 #define T_TA_WAIT(x) UPDATE(x, 5, 0) 111 112 enum lane_type { 113 CLOCK_LANE, 114 DATA_LANE_0, 115 DATA_LANE_1, 116 DATA_LANE_2, 117 DATA_LANE_3, 118 }; 119 120 struct mipi_dphy_timing { 121 unsigned int clkmiss; 122 unsigned int clkpost; 123 unsigned int clkpre; 124 unsigned int clkprepare; 125 unsigned int clksettle; 126 unsigned int clktermen; 127 unsigned int clktrail; 128 unsigned int clkzero; 129 unsigned int dtermen; 130 unsigned int eot; 131 unsigned int hsexit; 132 unsigned int hsprepare; 133 unsigned int hszero; 134 unsigned int hssettle; 135 unsigned int hsskip; 136 unsigned int hstrail; 137 unsigned int init; 138 unsigned int lpx; 139 unsigned int taget; 140 unsigned int tago; 141 unsigned int tasure; 142 unsigned int wakeup; 143 }; 144 145 struct inno_mipi_dphy_timing { 146 u8 lpx; 147 u8 hs_prepare; 148 u8 hs_zero; 149 u8 hs_trail; 150 u8 hs_exit; 151 u8 clk_post; 152 u8 wakup_h; 153 u8 wakup_l; 154 u8 clk_pre; 155 u8 ta_go; 156 u8 ta_sure; 157 u8 ta_wait; 158 }; 159 160 struct inno_mipi_dphy { 161 struct udevice *dev; 162 void __iomem *regs; 163 unsigned int lane_mbps; 164 int lanes; 165 }; 166 167 static const u32 lane_reg_offset[] = { 168 [CLOCK_LANE] = INNO_CLOCK_LANE_REG_BASE, 169 [DATA_LANE_0] = INNO_DATA_LANE_0_REG_BASE, 170 [DATA_LANE_1] = INNO_DATA_LANE_1_REG_BASE, 171 [DATA_LANE_2] = INNO_DATA_LANE_2_REG_BASE, 172 [DATA_LANE_3] = INNO_DATA_LANE_3_REG_BASE, 173 }; 174 175 #define FIXED_PARAM(_freq, _prepare, _clk_zero, _data_zero, _trail) \ 176 { \ 177 .max_freq = _freq, \ 178 .hs_prepare = _prepare, \ 179 .clk_lane = { \ 180 .hs_zero = _clk_zero, \ 181 }, \ 182 .data_lane = { \ 183 .hs_zero = _data_zero, \ 184 }, \ 185 .hs_trail = _trail, \ 186 } 187 188 struct fixed_param { 189 unsigned int max_freq; 190 u8 hs_prepare; 191 struct { 192 u8 hs_zero; 193 } clk_lane; 194 struct { 195 u8 hs_zero; 196 } data_lane; 197 u8 hs_trail; 198 }; 199 200 static const struct fixed_param fixed_param_table[] = { 201 FIXED_PARAM( 110, 0x20, 0x16, 0x02, 0x22), 202 FIXED_PARAM( 150, 0x06, 0x16, 0x03, 0x45), 203 FIXED_PARAM( 200, 0x18, 0x17, 0x04, 0x0b), 204 FIXED_PARAM( 250, 0x05, 0x17, 0x05, 0x16), 205 FIXED_PARAM( 300, 0x51, 0x18, 0x06, 0x2c), 206 FIXED_PARAM( 400, 0x64, 0x19, 0x07, 0x33), 207 FIXED_PARAM( 500, 0x20, 0x1b, 0x07, 0x4e), 208 FIXED_PARAM( 600, 0x6a, 0x1d, 0x08, 0x3a), 209 FIXED_PARAM( 700, 0x3e, 0x1e, 0x08, 0x6a), 210 FIXED_PARAM( 800, 0x21, 0x1f, 0x09, 0x29), 211 FIXED_PARAM(1000, 0x09, 0x20, 0x09, 0x27) 212 }; 213 214 static inline void inno_write(struct inno_mipi_dphy *inno, u32 reg, u32 val) 215 { 216 writel(val, inno->regs + reg); 217 } 218 219 static inline u32 inno_read(struct inno_mipi_dphy *inno, u32 reg) 220 { 221 return readl(inno->regs + reg); 222 } 223 224 static inline void inno_update_bits(struct inno_mipi_dphy *inno, u32 reg, 225 u32 mask, u32 val) 226 { 227 u32 tmp, orig; 228 229 orig = inno_read(inno, reg); 230 tmp = orig & ~mask; 231 tmp |= val & mask; 232 inno_write(inno, reg, tmp); 233 } 234 235 static void mipi_dphy_timing_get_default(struct mipi_dphy_timing *timing, 236 unsigned long period) 237 { 238 /* Global Operation Timing Parameters */ 239 timing->clkmiss = 0; 240 timing->clkpost = 70 + 52 * period; 241 timing->clkpre = 8 * period; 242 timing->clkprepare = 65; 243 timing->clksettle = 95; 244 timing->clktermen = 0; 245 timing->clktrail = 80; 246 timing->clkzero = 260; 247 timing->dtermen = 0; 248 timing->eot = 0; 249 timing->hsexit = 120; 250 timing->hsprepare = 65 + 4 * period; 251 timing->hszero = 145 + 6 * period; 252 timing->hssettle = 85 + 6 * period; 253 timing->hsskip = 40; 254 timing->hstrail = max(8 * period, 60 + 4 * period); 255 timing->init = 100000; 256 timing->lpx = 60; 257 timing->taget = 5 * timing->lpx; 258 timing->tago = 4 * timing->lpx; 259 timing->tasure = 2 * timing->lpx; 260 timing->wakeup = 1000000; 261 } 262 263 static void inno_mipi_dphy_timing_update(struct inno_mipi_dphy *inno, 264 enum lane_type lane_type, 265 struct inno_mipi_dphy_timing *t) 266 { 267 u32 base = lane_reg_offset[lane_type]; 268 u32 m, v; 269 270 m = T_HS_PREPARE_MASK; 271 v = T_HS_PREPARE(t->hs_prepare); 272 inno_update_bits(inno, base + T_HS_PREPARE_OFFSET, m, v); 273 274 m = T_HS_ZERO_MASK; 275 v = T_HS_ZERO(t->hs_zero); 276 inno_update_bits(inno, base + T_HS_ZERO_OFFSET, m, v); 277 278 m = T_HS_TRAIL_MASK; 279 v = T_HS_TRAIL(t->hs_trail); 280 inno_update_bits(inno, base + T_HS_TRAIL_OFFSET, m, v); 281 282 m = T_HS_EXIT_MASK; 283 v = T_HS_EXIT(t->hs_exit); 284 inno_update_bits(inno, base + T_HS_EXIT_OFFSET, m, v); 285 286 if (lane_type == CLOCK_LANE) { 287 m = T_CLK_POST_MASK; 288 v = T_CLK_POST(t->clk_post); 289 inno_update_bits(inno, base + T_CLK_POST_OFFSET, m, v); 290 291 m = T_CLK_PRE_MASK; 292 v = T_CLK_PRE(t->clk_pre); 293 inno_update_bits(inno, base + T_CLK_PRE_OFFSET, m, v); 294 } 295 296 m = T_WAKUP_H_MASK; 297 v = T_WAKUP_H(t->wakup_h); 298 inno_update_bits(inno, base + T_WAKUP_H_OFFSET, m, v); 299 300 m = T_WAKUP_L_MASK; 301 v = T_WAKUP_L(t->wakup_l); 302 inno_update_bits(inno, base + T_WAKUP_L_OFFSET, m, v); 303 304 m = T_LPX_MASK; 305 v = T_LPX(t->lpx); 306 inno_update_bits(inno, base + T_LPX_OFFSET, m, v); 307 308 m = T_TA_GO_MASK; 309 v = T_TA_GO(t->ta_go); 310 inno_update_bits(inno, base + T_TA_GO_OFFSET, m, v); 311 312 m = T_TA_SURE_MASK; 313 v = T_TA_SURE(t->ta_sure); 314 inno_update_bits(inno, base + T_TA_SURE_OFFSET, m, v); 315 316 m = T_TA_WAIT_MASK; 317 v = T_TA_WAIT(t->ta_wait); 318 inno_update_bits(inno, base + T_TA_WAIT_OFFSET, m, v); 319 } 320 321 static void inno_mipi_dphy_get_fixed_param(struct inno_mipi_dphy_timing *t, 322 unsigned int freq, 323 enum lane_type lane_type) 324 { 325 const struct fixed_param *param; 326 int i; 327 328 for (i = 0; i < ARRAY_SIZE(fixed_param_table); i++) 329 if (freq <= fixed_param_table[i].max_freq) 330 break; 331 332 if (i == ARRAY_SIZE(fixed_param_table)) 333 --i; 334 335 param = &fixed_param_table[i]; 336 337 if (lane_type == CLOCK_LANE) 338 t->hs_zero = param->clk_lane.hs_zero; 339 else 340 t->hs_zero = param->data_lane.hs_zero; 341 342 t->hs_prepare = param->hs_prepare; 343 t->hs_trail = param->hs_trail; 344 } 345 346 static void inno_mipi_dphy_lane_timing_init(struct inno_mipi_dphy *inno, 347 enum lane_type lane_type) 348 { 349 struct mipi_dphy_timing timing; 350 struct inno_mipi_dphy_timing data; 351 unsigned long txbyteclk, txclkesc, UI; 352 unsigned int esc_clk_div; 353 354 memset(&timing, 0, sizeof(timing)); 355 memset(&data, 0, sizeof(data)); 356 357 txbyteclk = inno->lane_mbps * USEC_PER_SEC / 8; 358 esc_clk_div = DIV_ROUND_UP(txbyteclk, 20000000); 359 txclkesc = txbyteclk / esc_clk_div; 360 UI = DIV_ROUND_CLOSEST(NSEC_PER_USEC, inno->lane_mbps); 361 362 debug("txbyteclk=%lu, txclkesc=%lu, esc_clk_div=%u, UI=%lu\n", 363 txbyteclk, txclkesc, esc_clk_div, UI); 364 365 mipi_dphy_timing_get_default(&timing, UI); 366 inno_mipi_dphy_get_fixed_param(&data, inno->lane_mbps, lane_type); 367 368 /* 369 * Ttxbyteclk * val >= Ths-exit 370 * Ttxbyteclk * val >= Tclk-post 371 * Ttxbyteclk * val >= Tclk-pre 372 * Ttxbyteclk * (2 + val) >= Tlpx 373 */ 374 data.hs_exit = DIV_ROUND_UP(timing.hsexit * txbyteclk, NSEC_PER_SEC); 375 data.clk_post = DIV_ROUND_UP(timing.clkpost * txbyteclk, NSEC_PER_SEC); 376 data.clk_pre = DIV_ROUND_UP(timing.clkpre * txbyteclk, NSEC_PER_SEC); 377 data.wakup_h = 0x3; 378 data.wakup_l = 0xff; 379 data.lpx = DIV_ROUND_UP(txbyteclk * timing.lpx, NSEC_PER_SEC); 380 if (data.lpx > 2) 381 data.lpx -= 2; 382 383 /* 384 * Ttxclkesc * val >= Tta-go 385 * Ttxclkesc * val >= Tta-sure 386 * Ttxclkesc * val >= Tta-wait 387 */ 388 data.ta_go = DIV_ROUND_UP(timing.tago * txclkesc, NSEC_PER_SEC); 389 data.ta_sure = DIV_ROUND_UP(timing.tasure * txclkesc, NSEC_PER_SEC); 390 data.ta_wait = DIV_ROUND_UP(timing.taget * txclkesc, NSEC_PER_SEC); 391 392 inno_mipi_dphy_timing_update(inno, lane_type, &data); 393 394 #define TIMING_NS(x, freq) (((x) * (DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq)))) 395 debug("hs-exit=%lu, clk-post=%lu, clk-pre=%lu, lpx=%lu\n", 396 TIMING_NS(data.hs_exit, txbyteclk), 397 TIMING_NS(data.clk_post, txbyteclk), 398 TIMING_NS(data.clk_pre, txbyteclk), 399 TIMING_NS(data.lpx + 2, txbyteclk)); 400 debug("ta-go=%lu, ta-sure=%lu, ta-wait=%lu\n", 401 TIMING_NS(data.ta_go, txclkesc), 402 TIMING_NS(data.ta_sure, txclkesc), 403 TIMING_NS(data.ta_wait, txclkesc)); 404 } 405 406 static unsigned long inno_mipi_dphy_pll_round_rate(unsigned long fin, 407 unsigned long fout, 408 u8 *prediv, u16 *fbdiv) 409 { 410 unsigned long best_freq = 0; 411 u8 min_prediv, max_prediv; 412 u8 _prediv, best_prediv = 0; 413 u16 _fbdiv, best_fbdiv = 0; 414 u32 min_delta = 0xffffffff; 415 416 fout *= 2; 417 418 min_prediv = DIV_ROUND_UP(fin, 40000000); 419 max_prediv = fin / 5000000; 420 421 for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { 422 u64 tmp; 423 u32 delta; 424 tmp = (u64)fout * _prediv; 425 do_div(tmp, fin); 426 _fbdiv = tmp; 427 if ((_fbdiv == 15) || (_fbdiv < 12) || (_fbdiv > 511)) 428 continue; 429 tmp = (u64)_fbdiv * fin; 430 do_div(tmp, _prediv); 431 432 delta = abs(fout - tmp); 433 if (delta < min_delta) { 434 best_prediv = _prediv; 435 best_fbdiv = _fbdiv; 436 min_delta = delta; 437 best_freq = tmp; 438 } 439 } 440 441 if (best_freq) { 442 *prediv = best_prediv; 443 *fbdiv = best_fbdiv; 444 } 445 446 return best_freq / 2; 447 } 448 449 static inline void inno_mipi_dphy_reset(struct inno_mipi_dphy *inno) 450 { 451 /* Reset analog */ 452 inno_update_bits(inno, INNO_PHY_POWER_CTRL, 453 ANALOG_RESET_MASK, ANALOG_RESET); 454 udelay(1); 455 inno_update_bits(inno, INNO_PHY_POWER_CTRL, 456 ANALOG_RESET_MASK, ANALOG_NORMAL); 457 /* Reset digital */ 458 inno_update_bits(inno, INNO_PHY_DIG_CTRL, 459 DIGITAL_RESET_MASK, DIGITAL_RESET); 460 udelay(1); 461 inno_update_bits(inno, INNO_PHY_DIG_CTRL, 462 DIGITAL_RESET_MASK, DIGITAL_NORMAL); 463 } 464 465 static void inno_mipi_dphy_timing_init(struct inno_mipi_dphy *inno) 466 { 467 switch (inno->lanes) { 468 case 4: 469 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_3); 470 /* Fall through */ 471 case 3: 472 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_2); 473 /* Fall through */ 474 case 2: 475 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_1); 476 /* Fall through */ 477 case 1: 478 default: 479 inno_mipi_dphy_lane_timing_init(inno, DATA_LANE_0); 480 inno_mipi_dphy_lane_timing_init(inno, CLOCK_LANE); 481 break; 482 } 483 } 484 485 static inline void inno_mipi_dphy_lane_enable(struct inno_mipi_dphy *inno) 486 { 487 u32 m = 0, v = 0; 488 489 switch (inno->lanes) { 490 case 4: 491 m |= DATA_LANE_3_EN_MASK; 492 v |= DATA_LANE_3_EN; 493 /* Fall through */ 494 case 3: 495 m |= DATA_LANE_2_EN_MASK; 496 v |= DATA_LANE_2_EN; 497 /* Fall through */ 498 case 2: 499 m |= DATA_LANE_1_EN_MASK; 500 v |= DATA_LANE_1_EN; 501 /* Fall through */ 502 default: 503 case 1: 504 m |= DATA_LANE_0_EN_MASK | CLK_LANE_EN_MASK; 505 v |= DATA_LANE_0_EN | CLK_LANE_EN; 506 break; 507 } 508 509 inno_update_bits(inno, INNO_PHY_LANE_CTRL, m, v); 510 } 511 512 static inline void inno_mipi_dphy_pll_ldo_disable(struct inno_mipi_dphy *inno) 513 { 514 inno_update_bits(inno, INNO_PHY_POWER_CTRL, 515 PLL_POWER_MASK | LDO_POWER_MASK, 516 PLL_POWER_DOWN | LDO_POWER_DOWN); 517 } 518 519 static inline void inno_mipi_dphy_pll_ldo_enable(struct inno_mipi_dphy *inno) 520 { 521 inno_update_bits(inno, INNO_PHY_POWER_CTRL, 522 PLL_POWER_MASK | LDO_POWER_MASK, 523 PLL_POWER_ON | LDO_POWER_ON); 524 } 525 526 static inline void inno_mipi_dphy_da_pwrok_enable(struct inno_mipi_dphy *inno) 527 { 528 inno_update_bits(inno, INNO_PHY_LANE_CTRL, PWROK_BP | PWROK, PWROK); 529 } 530 531 static inline void inno_mipi_dphy_da_pwrok_disable(struct inno_mipi_dphy *inno) 532 { 533 inno_update_bits(inno, INNO_PHY_LANE_CTRL, PWROK_BP | PWROK, PWROK_BP); 534 } 535 536 static inline void inno_mipi_dphy_bgpd_enable(struct inno_mipi_dphy *inno) 537 { 538 inno_update_bits(inno, INNO_PHY_LANE_CTRL, MIPI_BGPD, 0); 539 } 540 541 static inline void inno_mipi_dphy_bgpd_disable(struct inno_mipi_dphy *inno) 542 { 543 inno_update_bits(inno, INNO_PHY_LANE_CTRL, MIPI_BGPD, MIPI_BGPD); 544 inno_update_bits(inno, INNO_PHY_LVDS_CTRL, LVDS_BGPD, LVDS_BGPD); 545 } 546 547 static int inno_mipi_dphy_power_on(struct rockchip_phy *phy) 548 { 549 struct inno_mipi_dphy *inno = dev_get_priv(phy->dev); 550 551 inno_mipi_dphy_bgpd_enable(inno); 552 inno_mipi_dphy_da_pwrok_enable(inno); 553 inno_mipi_dphy_pll_ldo_enable(inno); 554 inno_mipi_dphy_lane_enable(inno); 555 inno_mipi_dphy_reset(inno); 556 inno_mipi_dphy_timing_init(inno); 557 udelay(1); 558 559 return 0; 560 } 561 562 static inline void inno_mipi_dphy_lane_disable(struct inno_mipi_dphy *inno) 563 { 564 inno_update_bits(inno, INNO_PHY_LANE_CTRL, 0x7c, 0x00); 565 } 566 567 static int inno_mipi_dphy_power_off(struct rockchip_phy *phy) 568 { 569 struct inno_mipi_dphy *inno = dev_get_priv(phy->dev); 570 571 inno_mipi_dphy_lane_disable(inno); 572 inno_mipi_dphy_pll_ldo_disable(inno); 573 inno_mipi_dphy_da_pwrok_disable(inno); 574 inno_mipi_dphy_bgpd_disable(inno); 575 576 return 0; 577 } 578 579 static unsigned long inno_mipi_dphy_set_pll(struct rockchip_phy *phy, 580 unsigned long rate) 581 { 582 struct inno_mipi_dphy *inno = dev_get_priv(phy->dev); 583 unsigned long fin, fout; 584 u16 fbdiv = 0; 585 u8 prediv = 0; 586 u32 m, v; 587 588 fin = 24000000; 589 fout = inno_mipi_dphy_pll_round_rate(fin, rate, &prediv, &fbdiv); 590 591 debug("%s: fin=%lu, fout=%lu, prediv=%u, fbdiv=%u\n", 592 __func__, fin, fout, prediv, fbdiv); 593 594 m = FBDIV_HI_MASK | PREDIV_MASK; 595 v = FBDIV_HI(fbdiv >> 8) | PREDIV(prediv); 596 inno_update_bits(inno, INNO_PHY_PLL_CTRL_0, m, v); 597 598 m = FBDIV_LO_MASK; 599 v = FBDIV_LO(fbdiv); 600 inno_update_bits(inno, INNO_PHY_PLL_CTRL_1, m, v); 601 602 inno->lane_mbps = fout / USEC_PER_SEC; 603 604 return fout; 605 } 606 607 static int inno_mipi_dphy_parse_dt(struct inno_mipi_dphy *inno) 608 { 609 struct udevice *dev = inno->dev; 610 611 inno->lanes = ofnode_read_u32_default(dev->node, "inno,lanes", 4); 612 613 return 0; 614 } 615 616 static int inno_mipi_dphy_init(struct rockchip_phy *phy) 617 { 618 struct inno_mipi_dphy *inno = dev_get_priv(phy->dev); 619 int ret; 620 621 ret = inno_mipi_dphy_parse_dt(inno); 622 if (ret) { 623 printf("%s: failed to parse DT\n", __func__); 624 return ret; 625 } 626 627 inno->regs = dev_read_addr_ptr(inno->dev); 628 629 return 0; 630 } 631 632 static const struct rockchip_phy_funcs inno_mipi_dphy_funcs = { 633 .init = inno_mipi_dphy_init, 634 .power_on = inno_mipi_dphy_power_on, 635 .power_off = inno_mipi_dphy_power_off, 636 .set_pll = inno_mipi_dphy_set_pll, 637 }; 638 639 static struct rockchip_phy inno_mipi_dphy_driver_data = { 640 .funcs = &inno_mipi_dphy_funcs, 641 }; 642 643 static const struct udevice_id inno_mipi_dphy_ids[] = { 644 { 645 .compatible = "rockchip,rv1108-mipi-dphy", 646 .data = (ulong)&inno_mipi_dphy_driver_data, 647 }, 648 {} 649 }; 650 651 static int inno_mipi_dphy_probe(struct udevice *dev) 652 { 653 struct inno_mipi_dphy *inno = dev_get_priv(dev); 654 struct rockchip_phy *phy = 655 (struct rockchip_phy *)dev_get_driver_data(dev); 656 657 inno->dev = dev; 658 phy->dev = dev; 659 660 return 0; 661 } 662 663 U_BOOT_DRIVER(inno_mipi_dphy) = { 664 .name = "inno_mipi_dphy", 665 .id = UCLASS_PHY, 666 .of_match = inno_mipi_dphy_ids, 667 .probe = inno_mipi_dphy_probe, 668 .priv_auto_alloc_size = sizeof(struct inno_mipi_dphy), 669 }; 670