hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c
....@@ -11,6 +11,82 @@
1111
1212 #include "maxim4c_api.h"
1313
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
+
1490 static int maxim4c_txphy_auto_init_deskew(maxim4c_t *maxim4c)
1591 {
1692 struct i2c_client *client = maxim4c->client;
....@@ -182,6 +258,11 @@
182258 reg_addr, MAXIM4C_I2C_REG_ADDR_16BITS,
183259 0xf4);
184260
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
+
185266 // Set dpll data rate
186267 reg_addr = 0x0415 + 0x03 * phy_idx;
187268 ret |= maxim4c_i2c_update_byte(client,
....@@ -349,6 +430,12 @@
349430 phy_cfg->clock_mode = value;
350431 }
351432
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
+
352439 sub_idx++;
353440 }
354441 }
....@@ -510,6 +597,9 @@
510597 // mipi txphy auto init deskew
511598 ret |= maxim4c_txphy_auto_init_deskew(maxim4c);
512599
600
+ // mipi txphy timing init
601
+ ret |= maxim4c_txphy_init_timing(maxim4c);
602
+
513603 if (ret) {
514604 dev_err(dev, "%s: txphy hw init error\n", __func__);
515605 return ret;
....@@ -529,6 +619,11 @@
529619 mipi_txphy->force_clock_out_en = 1;
530620 mipi_txphy->force_clk0_en = 0;
531621 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;
532627
533628 for (i = 0; i < MAXIM4C_TXPHY_ID_MAX; i++) {
534629 phy_cfg = &mipi_txphy->phy_cfg[i];
....@@ -541,6 +636,7 @@
541636 phy_cfg->vc_ext_en = 0;
542637 phy_cfg->clock_master = 0;
543638 phy_cfg->clock_mode = MAXIM4C_TXPHY_DPLL_PREDEF;
639
+ phy_cfg->ssc_ratio = 0;
544640 }
545641 }
546642 EXPORT_SYMBOL(maxim4c_mipi_txphy_data_init);