Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: rockchip: inno-dsidphy: Add support for rk3506

For MIPI mode, the inno-dsidphy found on RK3506 supports up to 2 lanes
and a maximum data rate of 1.5GHz.

Signed-off-by: Hongming Zou <hongming.zou@rock-chips.com>
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patch.msgid.link/20251106020632.92-7-kernel@airkyi.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Chaoyi Chen and committed by
Vinod Koul
785a9d5b 323c5c05

+88 -3
+88 -3
drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
··· 99 99 #define VOD_MID_RANGE 0x3 100 100 #define VOD_BIG_RANGE 0x7 101 101 #define VOD_MAX_RANGE 0xf 102 + /* Analog Register Part: reg18 */ 103 + #define LANE0_PRE_EMPHASIS_ENABLE_MASK BIT(6) 104 + #define LANE0_PRE_EMPHASIS_ENABLE BIT(6) 105 + #define LANE0_PRE_EMPHASIS_DISABLE 0 106 + #define LANE1_PRE_EMPHASIS_ENABLE_MASK BIT(5) 107 + #define LANE1_PRE_EMPHASIS_ENABLE BIT(5) 108 + #define LANE1_PRE_EMPHASIS_DISABLE 0 109 + /* Analog Register Part: reg19 */ 110 + #define PRE_EMPHASIS_RANGE_SET_MASK GENMASK(7, 6) 111 + #define PRE_EMPHASIS_RANGE_SET(x) UPDATE(x, 7, 6) 102 112 /* Analog Register Part: reg1E */ 103 113 #define PLL_MODE_SEL_MASK GENMASK(6, 5) 104 114 #define PLL_MODE_SEL_LVDS_MODE 0 105 115 #define PLL_MODE_SEL_MIPI_MODE BIT(5) 116 + /* Analog Register Part: reg20 */ 117 + #define LANE0_PRE_EMPHASIS_RANGE_SET_MASK GENMASK(7, 6) 118 + #define LANE0_PRE_EMPHASIS_RANGE_SET(x) UPDATE(x, 7, 6) 119 + /* Analog Register Part: reg21 */ 120 + #define LANE1_PRE_EMPHASIS_RANGE_SET_MASK GENMASK(7, 6) 121 + #define LANE1_PRE_EMPHASIS_RANGE_SET(x) UPDATE(x, 7, 6) 122 + #define PRE_EMPHASIS_MIN_RANGE 0x0 123 + #define PRE_EMPHASIS_MID_RANGE 0x1 124 + #define PRE_EMPHASIS_MAX_RANGE 0x2 125 + #define PRE_EMPHASIS_RESERVED_RANGE 0x3 106 126 /* Digital Register Part: reg00 */ 107 127 #define REG_DIG_RSTN_MASK BIT(0) 108 128 #define REG_DIG_RSTN_NORMAL BIT(0) ··· 213 193 214 194 enum phy_max_rate { 215 195 MAX_1GHZ, 196 + MAX_1_5GHZ, 216 197 MAX_2_5GHZ, 217 198 }; 218 199 ··· 221 200 const struct inno_mipi_dphy_timing *inno_mipi_dphy_timing_table; 222 201 const unsigned int num_timings; 223 202 enum phy_max_rate max_rate; 203 + unsigned int max_lanes; 224 204 }; 225 205 226 206 struct inno_dsidphy { ··· 278 256 { 700000000, 0x0, 0x3e, 0x1e, 0x08, 0x6a}, 279 257 { 800000000, 0x0, 0x21, 0x1f, 0x09, 0x29}, 280 258 {1000000000, 0x0, 0x09, 0x20, 0x09, 0x27}, 259 + }; 260 + 261 + static const 262 + struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1_5ghz[] = { 263 + { 110, 0x02, 0x7f, 0x16, 0x02, 0x02}, 264 + { 150, 0x02, 0x7f, 0x16, 0x03, 0x02}, 265 + { 200, 0x02, 0x7f, 0x17, 0x04, 0x02}, 266 + { 250, 0x02, 0x7f, 0x17, 0x05, 0x04}, 267 + { 300, 0x02, 0x7f, 0x18, 0x06, 0x04}, 268 + { 400, 0x03, 0x7e, 0x19, 0x07, 0x04}, 269 + { 500, 0x03, 0x7c, 0x1b, 0x07, 0x08}, 270 + { 600, 0x03, 0x70, 0x1d, 0x08, 0x10}, 271 + { 700, 0x05, 0x40, 0x1e, 0x08, 0x30}, 272 + { 800, 0x05, 0x02, 0x1f, 0x09, 0x30}, 273 + {1000, 0x05, 0x08, 0x20, 0x09, 0x30}, 274 + {1200, 0x06, 0x03, 0x32, 0x14, 0x0f}, 275 + {1400, 0x09, 0x03, 0x32, 0x14, 0x0f}, 276 + {1500, 0x0d, 0x42, 0x36, 0x0e, 0x0f}, 281 277 }; 282 278 283 279 static const ··· 412 372 u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait; 413 373 u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero; 414 374 unsigned int i; 375 + u32 val; 415 376 416 377 timings = inno->pdata->inno_mipi_dphy_timing_table; 417 378 ··· 431 390 if (inno->pdata->max_rate == MAX_2_5GHZ) { 432 391 phy_update_bits(inno, REGISTER_PART_ANALOG, 0x08, 433 392 PLL_POST_DIV_ENABLE_MASK, PLL_POST_DIV_ENABLE); 393 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b, 394 + CLOCK_LANE_VOD_RANGE_SET_MASK, 395 + CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE)); 396 + } else if (inno->pdata->max_rate == MAX_1_5GHZ) { 397 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18, 398 + LANE0_PRE_EMPHASIS_ENABLE_MASK, LANE0_PRE_EMPHASIS_ENABLE); 399 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18, 400 + LANE1_PRE_EMPHASIS_ENABLE_MASK, LANE1_PRE_EMPHASIS_ENABLE); 401 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x19, 402 + PRE_EMPHASIS_RANGE_SET_MASK, 403 + PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE)); 404 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1a, 405 + LANE0_PRE_EMPHASIS_RANGE_SET_MASK, 406 + LANE0_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE)); 407 + phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1b, 408 + LANE1_PRE_EMPHASIS_RANGE_SET_MASK, 409 + LANE1_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE)); 434 410 phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b, 435 411 CLOCK_LANE_VOD_RANGE_SET_MASK, 436 412 CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE)); ··· 576 518 T_TA_WAIT_CNT(ta_wait)); 577 519 } 578 520 579 - /* Enable all lanes on analog part */ 521 + /* Enable lanes on analog part */ 522 + switch (inno->pdata->max_lanes) { 523 + case 1: 524 + val = LANE_EN_0; 525 + break; 526 + case 2: 527 + val = LANE_EN_0 | LANE_EN_1; 528 + break; 529 + case 3: 530 + val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2; 531 + break; 532 + case 4: 533 + default: 534 + val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2 | LANE_EN_3; 535 + break; 536 + } 537 + 580 538 phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00, 581 - LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 | 582 - LANE_EN_1 | LANE_EN_0); 539 + LANE_EN_MASK, LANE_EN_CK | val); 583 540 } 584 541 585 542 static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno) ··· 753 680 .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1ghz, 754 681 .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1ghz), 755 682 .max_rate = MAX_1GHZ, 683 + .max_lanes = 4, 684 + }; 685 + 686 + static const struct inno_video_phy_plat_data max_1_5ghz_video_phy_plat_data = { 687 + .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1_5ghz, 688 + .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1_5ghz), 689 + .max_rate = MAX_1_5GHZ, 690 + .max_lanes = 2, 756 691 }; 757 692 758 693 static const struct inno_video_phy_plat_data max_2_5ghz_video_phy_plat_data = { 759 694 .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_2_5ghz, 760 695 .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_2_5ghz), 761 696 .max_rate = MAX_2_5GHZ, 697 + .max_lanes = 4, 762 698 }; 763 699 764 700 static int inno_dsidphy_probe(struct platform_device *pdev) ··· 849 767 }, { 850 768 .compatible = "rockchip,rk3368-dsi-dphy", 851 769 .data = &max_1ghz_video_phy_plat_data, 770 + }, { 771 + .compatible = "rockchip,rk3506-dsi-dphy", 772 + .data = &max_1_5ghz_video_phy_plat_data, 852 773 }, { 853 774 .compatible = "rockchip,rk3568-dsi-dphy", 854 775 .data = &max_2_5ghz_video_phy_plat_data,