| .. | .. |
|---|
| 11 | 11 | |
|---|
| 12 | 12 | #include "maxim4c_api.h" |
|---|
| 13 | 13 | |
|---|
| 14 | +static int maxim4c_txphy_init_timing(maxim4c_t *maxim4c) |
|---|
| 15 | +{ |
|---|
| 16 | + struct i2c_client *client = maxim4c->client; |
|---|
| 17 | + int ret = 0; |
|---|
| 18 | + u16 reg_addr = 0; |
|---|
| 19 | + u8 reg_mask; |
|---|
| 20 | + u8 timing; |
|---|
| 21 | + u8 phy_idx = 0; |
|---|
| 22 | + |
|---|
| 23 | + if (!maxim4c->mipi_txphy.timing_override_en) |
|---|
| 24 | + return 0; |
|---|
| 25 | + |
|---|
| 26 | + timing = ((maxim4c->mipi_txphy.timing.t_hs_przero & 0x3) << 6 | |
|---|
| 27 | + (maxim4c->mipi_txphy.timing.t_hs_prep & 0x3) << 4 | |
|---|
| 28 | + (maxim4c->mipi_txphy.timing.t_clk_trail & 0x3) << 2 | |
|---|
| 29 | + (maxim4c->mipi_txphy.timing.t_clk_przero & 0x3) << 0); |
|---|
| 30 | + |
|---|
| 31 | + ret |= maxim4c_i2c_write_byte(client, 0x08A1, |
|---|
| 32 | + MAXIM4C_I2C_REG_ADDR_16BITS, timing); |
|---|
| 33 | + |
|---|
| 34 | + reg_mask = 0x0F; |
|---|
| 35 | + timing = ((maxim4c->mipi_txphy.timing.t_lpx & 0x3) << 2 | |
|---|
| 36 | + (maxim4c->mipi_txphy.timing.t_hs_trail & 0x3) << 0); |
|---|
| 37 | + |
|---|
| 38 | + ret |= maxim4c_i2c_update_byte( |
|---|
| 39 | + client, 0x08A2, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing); |
|---|
| 40 | + |
|---|
| 41 | + reg_mask = (0x3 << 6); |
|---|
| 42 | + timing = (maxim4c->mipi_txphy.timing.t_lpxesc & 0x3) << 6; |
|---|
| 43 | + ret |= maxim4c_i2c_update_byte( |
|---|
| 44 | + client, 0x08A5, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing); |
|---|
| 45 | + |
|---|
| 46 | + reg_mask = (0x7 << 5); |
|---|
| 47 | + timing = (maxim4c->mipi_txphy.timing.t_lpxesc & 0x7) << 5; |
|---|
| 48 | + ret |= maxim4c_i2c_update_byte( |
|---|
| 49 | + client, 0x08A8, MAXIM4C_I2C_REG_ADDR_16BITS, reg_mask, timing); |
|---|
| 50 | + |
|---|
| 51 | + for (phy_idx = 0; phy_idx < MAXIM4C_TXPHY_ID_MAX; phy_idx++) { |
|---|
| 52 | + reg_mask = 0xFF; |
|---|
| 53 | + reg_addr = 0x0905 + 0x40 * phy_idx; |
|---|
| 54 | + timing = maxim4c->mipi_txphy.timing.csi2_t_pre; |
|---|
| 55 | + ret |= maxim4c_i2c_update_byte(client, reg_addr, |
|---|
| 56 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 57 | + reg_mask, timing); |
|---|
| 58 | + |
|---|
| 59 | + reg_addr = 0x0906 + 0x40 * phy_idx; |
|---|
| 60 | + timing = maxim4c->mipi_txphy.timing.csi2_t_post; |
|---|
| 61 | + ret |= maxim4c_i2c_update_byte(client, reg_addr, |
|---|
| 62 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 63 | + reg_mask, timing); |
|---|
| 64 | + |
|---|
| 65 | + reg_addr = 0x0907 + 0x40 * phy_idx; |
|---|
| 66 | + timing = maxim4c->mipi_txphy.timing.csi2_tx_gap; |
|---|
| 67 | + ret |= maxim4c_i2c_update_byte(client, reg_addr, |
|---|
| 68 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 69 | + reg_mask, timing); |
|---|
| 70 | + |
|---|
| 71 | + reg_addr = 0x0908 + 0x40 * phy_idx; |
|---|
| 72 | + timing = maxim4c->mipi_txphy.timing.csi2_twakeup & 0xFF; |
|---|
| 73 | + ret |= maxim4c_i2c_update_byte(client, reg_addr, |
|---|
| 74 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 75 | + reg_mask, timing); |
|---|
| 76 | + timing = (maxim4c->mipi_txphy.timing.csi2_twakeup >> 8) & 0xFF; |
|---|
| 77 | + ret |= maxim4c_i2c_update_byte(client, reg_addr + 1, |
|---|
| 78 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 79 | + reg_mask, timing); |
|---|
| 80 | + reg_mask = 0x7; |
|---|
| 81 | + timing = (maxim4c->mipi_txphy.timing.csi2_twakeup >> 16) & 0x7; |
|---|
| 82 | + ret |= maxim4c_i2c_update_byte(client, reg_addr + 2, |
|---|
| 83 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 84 | + reg_mask, timing); |
|---|
| 85 | + } |
|---|
| 86 | + |
|---|
| 87 | + return ret; |
|---|
| 88 | +} |
|---|
| 89 | + |
|---|
| 14 | 90 | static int maxim4c_txphy_auto_init_deskew(maxim4c_t *maxim4c) |
|---|
| 15 | 91 | { |
|---|
| 16 | 92 | struct i2c_client *client = maxim4c->client; |
|---|
| .. | .. |
|---|
| 182 | 258 | reg_addr, MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 183 | 259 | 0xf4); |
|---|
| 184 | 260 | |
|---|
| 261 | + reg_addr = 0x1C03 + 0x100 * phy_idx; |
|---|
| 262 | + ret |= maxim4c_i2c_update_byte(client, reg_addr, |
|---|
| 263 | + MAXIM4C_I2C_REG_ADDR_16BITS, |
|---|
| 264 | + 0x07, phy_cfg->ssc_ratio); |
|---|
| 265 | + |
|---|
| 185 | 266 | // Set dpll data rate |
|---|
| 186 | 267 | reg_addr = 0x0415 + 0x03 * phy_idx; |
|---|
| 187 | 268 | ret |= maxim4c_i2c_update_byte(client, |
|---|
| .. | .. |
|---|
| 349 | 430 | phy_cfg->clock_mode = value; |
|---|
| 350 | 431 | } |
|---|
| 351 | 432 | |
|---|
| 433 | + ret = of_property_read_u32(node, "ssc-ratio", &value); |
|---|
| 434 | + if (ret == 0) { |
|---|
| 435 | + dev_info(dev, "ssc-ratio property: %d", value); |
|---|
| 436 | + phy_cfg->ssc_ratio = value; |
|---|
| 437 | + } |
|---|
| 438 | + |
|---|
| 352 | 439 | sub_idx++; |
|---|
| 353 | 440 | } |
|---|
| 354 | 441 | } |
|---|
| .. | .. |
|---|
| 510 | 597 | // mipi txphy auto init deskew |
|---|
| 511 | 598 | ret |= maxim4c_txphy_auto_init_deskew(maxim4c); |
|---|
| 512 | 599 | |
|---|
| 600 | + // mipi txphy timing init |
|---|
| 601 | + ret |= maxim4c_txphy_init_timing(maxim4c); |
|---|
| 602 | + |
|---|
| 513 | 603 | if (ret) { |
|---|
| 514 | 604 | dev_err(dev, "%s: txphy hw init error\n", __func__); |
|---|
| 515 | 605 | return ret; |
|---|
| .. | .. |
|---|
| 529 | 619 | mipi_txphy->force_clock_out_en = 1; |
|---|
| 530 | 620 | mipi_txphy->force_clk0_en = 0; |
|---|
| 531 | 621 | mipi_txphy->force_clk3_en = 0; |
|---|
| 622 | + mipi_txphy->timing.t_lpx = 1; |
|---|
| 623 | + mipi_txphy->timing.csi2_t_pre = 0x71; |
|---|
| 624 | + mipi_txphy->timing.csi2_t_post = 0x19; |
|---|
| 625 | + mipi_txphy->timing.csi2_tx_gap = 0x1C; |
|---|
| 626 | + mipi_txphy->timing.csi2_twakeup = 0x100; |
|---|
| 532 | 627 | |
|---|
| 533 | 628 | for (i = 0; i < MAXIM4C_TXPHY_ID_MAX; i++) { |
|---|
| 534 | 629 | phy_cfg = &mipi_txphy->phy_cfg[i]; |
|---|
| .. | .. |
|---|
| 541 | 636 | phy_cfg->vc_ext_en = 0; |
|---|
| 542 | 637 | phy_cfg->clock_master = 0; |
|---|
| 543 | 638 | phy_cfg->clock_mode = MAXIM4C_TXPHY_DPLL_PREDEF; |
|---|
| 639 | + phy_cfg->ssc_ratio = 0; |
|---|
| 544 | 640 | } |
|---|
| 545 | 641 | } |
|---|
| 546 | 642 | EXPORT_SYMBOL(maxim4c_mipi_txphy_data_init); |
|---|