Lines Matching +full:disconnection +full:- +full:compensate
1 // SPDX-License-Identifier: GPL-2.0
3 * phy-rtk-usb2.c RTK usb2.0 PHY driver
15 #include <linux/nvmem-consumer.h>
128 return (int)((((addr) - PAGE_START) & 0x7) + in page_addr_to_array_index()
129 ((((addr) - PAGE_START) & 0x10) >> 1)); in page_addr_to_array_index()
150 return -ETIMEDOUT; in utmi_wait_register()
158 void __iomem *reg_gusb2phyacc0 = phy_reg->reg_gusb2phyacc0; in rtk_phy_read()
162 addr -= OFFEST_PHY_READ; in rtk_phy_read()
191 void __iomem *reg_wrap_vstatus = phy_reg->reg_wrap_vstatus; in rtk_phy_write()
192 void __iomem *reg_gusb2phyacc0 = phy_reg->reg_gusb2phyacc0; in rtk_phy_write()
193 int shift_bits = phy_reg->vstatus_index * 8; in rtk_phy_write()
235 return -EINVAL; in rtk_phy_set_page()
243 s32 dc_disconnect_mask = phy_cfg->dc_disconnect_mask; in __updated_dc_disconnect_level_page0_0xe4()
247 + phy_parameter->efuse_usb_dc_dis in __updated_dc_disconnect_level_page0_0xe4()
248 + phy_parameter->disconnection_compensate; in __updated_dc_disconnect_level_page0_0xe4()
274 phy_cfg = rtk_phy->phy_cfg; in update_dc_disconnect_level_at_page0()
275 phy_reg = &phy_parameter->phy_reg; in update_dc_disconnect_level_at_page0()
278 phy_data_page = phy_cfg->page0; in update_dc_disconnect_level_at_page0()
283 if (!phy_data->addr) { in update_dc_disconnect_level_at_page0()
284 phy_data->addr = PAGE0_0XE4; in update_dc_disconnect_level_at_page0()
285 phy_data->data = rtk_phy_read(phy_reg, PAGE0_0XE4); in update_dc_disconnect_level_at_page0()
288 addr = phy_data->addr; in update_dc_disconnect_level_at_page0()
289 data = phy_data->data; in update_dc_disconnect_level_at_page0()
290 dc_disconnect_mask = phy_cfg->dc_disconnect_mask; in update_dc_disconnect_level_at_page0()
299 dev_err(rtk_phy->dev, in update_dc_disconnect_level_at_page0()
309 s32 dc_disconnect_mask = phy_cfg->dc_disconnect_mask; in __updated_dc_disconnect_level_page1_0xe2()
311 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) { in __updated_dc_disconnect_level_page1_0xe2()
313 + phy_parameter->efuse_usb_dc_dis in __updated_dc_disconnect_level_page1_0xe2()
314 + phy_parameter->disconnection_compensate; in __updated_dc_disconnect_level_page1_0xe2()
316 if (phy_parameter->efuse_usb_dc_dis) in __updated_dc_disconnect_level_page1_0xe2()
317 val = (s32)(phy_parameter->efuse_usb_dc_dis + in __updated_dc_disconnect_level_page1_0xe2()
318 phy_parameter->disconnection_compensate); in __updated_dc_disconnect_level_page1_0xe2()
321 phy_parameter->disconnection_compensate); in __updated_dc_disconnect_level_page1_0xe2()
346 phy_cfg = rtk_phy->phy_cfg; in update_dc_disconnect_level_at_page1()
347 phy_reg = &phy_parameter->phy_reg; in update_dc_disconnect_level_at_page1()
350 phy_data_page = phy_cfg->page1; in update_dc_disconnect_level_at_page1()
355 if (!phy_data->addr) { in update_dc_disconnect_level_at_page1()
356 phy_data->addr = PAGE1_0XE2; in update_dc_disconnect_level_at_page1()
357 phy_data->data = rtk_phy_read(phy_reg, PAGE1_0XE2); in update_dc_disconnect_level_at_page1()
360 addr = phy_data->addr; in update_dc_disconnect_level_at_page1()
361 data = phy_data->data; in update_dc_disconnect_level_at_page1()
362 dc_disconnect_mask = phy_cfg->dc_disconnect_mask; in update_dc_disconnect_level_at_page1()
370 dev_err(rtk_phy->dev, in update_dc_disconnect_level_at_page1()
378 struct phy_cfg *phy_cfg = rtk_phy->phy_cfg; in update_dc_disconnect_level()
380 if (phy_cfg->usb_dc_disconnect_at_page0) in update_dc_disconnect_level()
389 s32 driving_level_compensate = phy_parameter->driving_level_compensate; in __update_dc_driving_page0_0xe4()
390 s32 dc_driving_mask = phy_cfg->dc_driving_mask; in __update_dc_driving_page0_0xe4()
394 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) { in __update_dc_driving_page0_0xe4()
396 + phy_parameter->efuse_usb_dc_cal; in __update_dc_driving_page0_0xe4()
398 if (phy_parameter->efuse_usb_dc_cal) in __update_dc_driving_page0_0xe4()
399 val = (s32)((phy_parameter->efuse_usb_dc_cal & dc_driving_mask) in __update_dc_driving_page0_0xe4()
421 phy_reg = &phy_parameter->phy_reg; in update_dc_driving_level()
422 phy_cfg = rtk_phy->phy_cfg; in update_dc_driving_level()
423 if (!phy_cfg->page0[4].addr) { in update_dc_driving_level()
425 phy_cfg->page0[4].addr = PAGE0_0XE4; in update_dc_driving_level()
426 phy_cfg->page0[4].data = rtk_phy_read(phy_reg, PAGE0_0XE4); in update_dc_driving_level()
429 if (phy_parameter->driving_level != DEFAULT_DC_DRIVING_VALUE) { in update_dc_driving_level()
434 data = phy_cfg->page0[4].data; in update_dc_driving_level()
435 dc_driving_mask = phy_cfg->dc_driving_mask; in update_dc_driving_level()
438 dev_dbg(rtk_phy->dev, "%s driving_level=%d => dts driving_level=%d\n", in update_dc_driving_level()
439 __func__, driving_level, phy_parameter->driving_level); in update_dc_driving_level()
441 phy_cfg->page0[4].data = (data & (~dc_driving_mask)) | in update_dc_driving_level()
442 (phy_parameter->driving_level & dc_driving_mask); in update_dc_driving_level()
445 phy_cfg->page0[4].data = __update_dc_driving_page0_0xe4(phy_cfg, in update_dc_driving_level()
447 phy_cfg->page0[4].data); in update_dc_driving_level()
456 phy_cfg = rtk_phy->phy_cfg; in update_hs_clk_select()
457 phy_reg = &phy_parameter->phy_reg; in update_hs_clk_select()
459 if (phy_parameter->inverse_hstx_sync_clock) { in update_hs_clk_select()
460 if (!phy_cfg->page0[6].addr) { in update_hs_clk_select()
462 phy_cfg->page0[6].addr = PAGE0_0XE6; in update_hs_clk_select()
463 phy_cfg->page0[6].data = rtk_phy_read(phy_reg, PAGE0_0XE6); in update_hs_clk_select()
466 phy_cfg->page0[6].data = phy_cfg->page0[6].data | HS_CLK_SELECT; in update_hs_clk_select()
480 phy_cfg = rtk_phy->phy_cfg; in do_rtk_phy_toggle()
481 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index]; in do_rtk_phy_toggle()
482 phy_reg = &phy_parameter->phy_reg; in do_rtk_phy_toggle()
484 if (!phy_cfg->do_toggle) in do_rtk_phy_toggle()
487 if (phy_cfg->is_double_sensitivity_mode) in do_rtk_phy_toggle()
503 if (!phy_cfg->do_toggle_driving) in do_rtk_phy_toggle()
509 phy_data_page = phy_cfg->page0; in do_rtk_phy_toggle()
522 phy_cfg->driving_updated_for_dev_dis; in do_rtk_phy_toggle()
523 s32 dc_driving_mask = phy_cfg->dc_driving_mask; in do_rtk_phy_toggle()
568 phy_cfg = rtk_phy->phy_cfg; in do_rtk_phy_init()
569 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index]; in do_rtk_phy_init()
570 phy_reg = &phy_parameter->phy_reg; in do_rtk_phy_init()
572 if (phy_cfg->use_default_parameter) { in do_rtk_phy_init()
573 dev_dbg(rtk_phy->dev, "%s phy#%d use default parameter\n", in do_rtk_phy_init()
579 phy_data_page = phy_cfg->page0; in do_rtk_phy_init()
582 for (i = 0; i < phy_cfg->page0_size; i++) { in do_rtk_phy_init()
584 u8 addr = phy_data->addr; in do_rtk_phy_init()
585 u8 data = phy_data->data; in do_rtk_phy_init()
591 dev_err(rtk_phy->dev, in do_rtk_phy_init()
594 return -EINVAL; in do_rtk_phy_init()
599 phy_data_page = phy_cfg->page1; in do_rtk_phy_init()
602 for (i = 0; i < phy_cfg->page1_size; i++) { in do_rtk_phy_init()
604 u8 addr = phy_data->addr; in do_rtk_phy_init()
605 u8 data = phy_data->data; in do_rtk_phy_init()
611 dev_err(rtk_phy->dev, in do_rtk_phy_init()
614 return -EINVAL; in do_rtk_phy_init()
618 if (phy_cfg->page2_size == 0) in do_rtk_phy_init()
622 phy_data_page = phy_cfg->page2; in do_rtk_phy_init()
625 for (i = 0; i < phy_cfg->page2_size; i++) { in do_rtk_phy_init()
627 u8 addr = phy_data->addr; in do_rtk_phy_init()
628 u8 data = phy_data->data; in do_rtk_phy_init()
634 dev_err(rtk_phy->dev, in do_rtk_phy_init()
637 return -EINVAL; in do_rtk_phy_init()
654 return -EINVAL; in rtk_phy_init()
656 for (i = 0; i < rtk_phy->num_phy; i++) in rtk_phy_init()
659 dev_dbg(rtk_phy->dev, "Initialized RTK USB 2.0 PHY (take %dms)\n", in rtk_phy_init()
660 jiffies_to_msecs(jiffies - phy_init_time)); in rtk_phy_init()
673 if (index > rtk_phy->num_phy) { in rtk_phy_toggle()
674 dev_err(rtk_phy->dev, "%s: The port=%d is not in usb phy (num_phy=%d)\n", in rtk_phy_toggle()
675 __func__, index, rtk_phy->num_phy); in rtk_phy_toggle()
686 dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port); in rtk_phy_connect()
696 dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port); in rtk_phy_disconnect()
724 struct rtk_phy *rtk_phy = s->private; in rtk_usb2_parameter_show()
728 phy_cfg = rtk_phy->phy_cfg; in rtk_usb2_parameter_show()
732 phy_cfg->check_efuse ? "Enable" : "Disable"); in rtk_usb2_parameter_show()
734 phy_cfg->check_efuse_version); in rtk_usb2_parameter_show()
736 phy_cfg->efuse_dc_driving_rate); in rtk_usb2_parameter_show()
738 phy_cfg->dc_driving_mask); in rtk_usb2_parameter_show()
740 phy_cfg->efuse_dc_disconnect_rate); in rtk_usb2_parameter_show()
742 phy_cfg->dc_disconnect_mask); in rtk_usb2_parameter_show()
744 phy_cfg->usb_dc_disconnect_at_page0 ? "true" : "false"); in rtk_usb2_parameter_show()
746 phy_cfg->do_toggle ? "Enable" : "Disable"); in rtk_usb2_parameter_show()
748 phy_cfg->do_toggle_driving ? "Enable" : "Disable"); in rtk_usb2_parameter_show()
750 phy_cfg->driving_updated_for_dev_dis); in rtk_usb2_parameter_show()
752 phy_cfg->use_default_parameter ? "Enable" : "Disable"); in rtk_usb2_parameter_show()
754 phy_cfg->is_double_sensitivity_mode ? "Enable" : "Disable"); in rtk_usb2_parameter_show()
756 for (index = 0; index < rtk_phy->num_phy; index++) { in rtk_usb2_parameter_show()
761 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index]; in rtk_usb2_parameter_show()
762 phy_reg = &phy_parameter->phy_reg; in rtk_usb2_parameter_show()
768 phy_data_page = phy_cfg->page0; in rtk_usb2_parameter_show()
771 for (i = 0; i < phy_cfg->page0_size; i++) { in rtk_usb2_parameter_show()
774 u8 data = phy_data->data; in rtk_usb2_parameter_show()
777 if (phy_data->addr) in rtk_usb2_parameter_show()
787 phy_data_page = phy_cfg->page1; in rtk_usb2_parameter_show()
790 for (i = 0; i < phy_cfg->page1_size; i++) { in rtk_usb2_parameter_show()
793 u8 data = phy_data->data; in rtk_usb2_parameter_show()
796 if (phy_data->addr) in rtk_usb2_parameter_show()
804 if (phy_cfg->page2_size == 0) in rtk_usb2_parameter_show()
809 phy_data_page = phy_cfg->page2; in rtk_usb2_parameter_show()
812 for (i = 0; i < phy_cfg->page2_size; i++) { in rtk_usb2_parameter_show()
815 u8 data = phy_data->data; in rtk_usb2_parameter_show()
818 if (phy_data->addr) in rtk_usb2_parameter_show()
829 (int)phy_parameter->efuse_usb_dc_cal); in rtk_usb2_parameter_show()
831 (int)phy_parameter->efuse_usb_dc_dis); in rtk_usb2_parameter_show()
833 phy_parameter->inverse_hstx_sync_clock ? "Enable" : "Disable"); in rtk_usb2_parameter_show()
835 phy_parameter->driving_level); in rtk_usb2_parameter_show()
837 phy_parameter->driving_level_compensate); in rtk_usb2_parameter_show()
839 phy_parameter->disconnection_compensate); in rtk_usb2_parameter_show()
854 rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev), in create_debug_files()
857 debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy, in create_debug_files()
863 debugfs_remove_recursive(rtk_phy->debug_dir); in remove_debug_files()
873 struct phy_cfg *phy_cfg = rtk_phy->phy_cfg; in get_phy_data_by_efuse()
880 if (!phy_cfg->check_efuse) in get_phy_data_by_efuse()
884 cell = nvmem_cell_get(rtk_phy->dev, "usb-dc-cal"); in get_phy_data_by_efuse()
886 dev_dbg(rtk_phy->dev, "%s no usb-dc-cal: %ld\n", in get_phy_data_by_efuse()
894 value = buf[0] & phy_cfg->dc_driving_mask; in get_phy_data_by_efuse()
900 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) { in get_phy_data_by_efuse()
901 int rate = phy_cfg->efuse_dc_driving_rate; in get_phy_data_by_efuse()
904 phy_parameter->efuse_usb_dc_cal = (int8_t)(value * rate); in get_phy_data_by_efuse()
906 phy_parameter->efuse_usb_dc_cal = -(int8_t) in get_phy_data_by_efuse()
910 dev_dbg(rtk_phy->dev, "For groot IC we need a workaround to adjust efuse_usb_dc_cal\n"); in get_phy_data_by_efuse()
912 /* We don't multiple dc_cal_rate=2 for positive dc cal compensate */ in get_phy_data_by_efuse()
914 phy_parameter->efuse_usb_dc_cal = (int8_t)(value); in get_phy_data_by_efuse()
916 /* We set max dc cal compensate is 0x8 if otp is 0x7 */ in get_phy_data_by_efuse()
918 phy_parameter->efuse_usb_dc_cal = (int8_t)(value + 1); in get_phy_data_by_efuse()
921 phy_parameter->efuse_usb_dc_cal = value & phy_cfg->dc_driving_mask; in get_phy_data_by_efuse()
926 cell = nvmem_cell_get(rtk_phy->dev, "usb-dc-dis"); in get_phy_data_by_efuse()
928 dev_dbg(rtk_phy->dev, "%s no usb-dc-dis: %ld\n", in get_phy_data_by_efuse()
936 value = buf[0] & phy_cfg->dc_disconnect_mask; in get_phy_data_by_efuse()
942 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) { in get_phy_data_by_efuse()
943 int rate = phy_cfg->efuse_dc_disconnect_rate; in get_phy_data_by_efuse()
946 phy_parameter->efuse_usb_dc_dis = (int8_t)(value * rate); in get_phy_data_by_efuse()
948 phy_parameter->efuse_usb_dc_dis = -(int8_t) in get_phy_data_by_efuse()
951 phy_parameter->efuse_usb_dc_dis = value & phy_cfg->dc_disconnect_mask; in get_phy_data_by_efuse()
960 struct device *dev = rtk_phy->dev; in parse_phy_data()
961 struct device_node *np = dev->of_node; in parse_phy_data()
966 rtk_phy->phy_parameter = devm_kzalloc(dev, sizeof(struct phy_parameter) * in parse_phy_data()
967 rtk_phy->num_phy, GFP_KERNEL); in parse_phy_data()
968 if (!rtk_phy->phy_parameter) in parse_phy_data()
969 return -ENOMEM; in parse_phy_data()
971 for (index = 0; index < rtk_phy->num_phy; index++) { in parse_phy_data()
972 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index]; in parse_phy_data()
974 phy_parameter->phy_reg.reg_wrap_vstatus = of_iomap(np, 0); in parse_phy_data()
975 phy_parameter->phy_reg.reg_gusb2phyacc0 = of_iomap(np, 1) + index; in parse_phy_data()
976 phy_parameter->phy_reg.vstatus_index = index; in parse_phy_data()
978 if (of_property_read_bool(np, "realtek,inverse-hstx-sync-clock")) in parse_phy_data()
979 phy_parameter->inverse_hstx_sync_clock = true; in parse_phy_data()
981 phy_parameter->inverse_hstx_sync_clock = false; in parse_phy_data()
983 if (of_property_read_u32_index(np, "realtek,driving-level", in parse_phy_data()
984 index, &phy_parameter->driving_level)) in parse_phy_data()
985 phy_parameter->driving_level = DEFAULT_DC_DRIVING_VALUE; in parse_phy_data()
987 if (of_property_read_u32_index(np, "realtek,driving-level-compensate", in parse_phy_data()
988 index, &phy_parameter->driving_level_compensate)) in parse_phy_data()
989 phy_parameter->driving_level_compensate = 0; in parse_phy_data()
991 if (of_property_read_u32_index(np, "realtek,disconnection-compensate", in parse_phy_data()
992 index, &phy_parameter->disconnection_compensate)) in parse_phy_data()
993 phy_parameter->disconnection_compensate = 0; in parse_phy_data()
1008 struct device *dev = &pdev->dev; in rtk_usb2phy_probe()
1017 return -EINVAL; in rtk_usb2phy_probe()
1022 return -ENOMEM; in rtk_usb2phy_probe()
1024 rtk_phy->dev = &pdev->dev; in rtk_usb2phy_probe()
1025 rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL); in rtk_usb2phy_probe()
1027 memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg)); in rtk_usb2phy_probe()
1029 rtk_phy->num_phy = phy_cfg->num_phy; in rtk_usb2phy_probe()
1037 generic_phy = devm_phy_create(rtk_phy->dev, NULL, &ops); in rtk_usb2phy_probe()
1043 phy_provider = devm_of_phy_provider_register(rtk_phy->dev, in rtk_usb2phy_probe()
1286 { .compatible = "realtek,rtd1295-usb2phy", .data = &rtd1295_phy_cfg },
1287 { .compatible = "realtek,rtd1312c-usb2phy", .data = &rtd1312c_phy_cfg },
1288 { .compatible = "realtek,rtd1315e-usb2phy", .data = &rtd1315e_phy_cfg },
1289 { .compatible = "realtek,rtd1319-usb2phy", .data = &rtd1319_phy_cfg },
1290 { .compatible = "realtek,rtd1319d-usb2phy", .data = &rtd1319d_phy_cfg },
1291 { .compatible = "realtek,rtd1395-usb2phy", .data = &rtd1395_phy_cfg },
1292 { .compatible = "realtek,rtd1395-usb2phy-2port", .data = &rtd1395_phy_cfg_2port },
1293 { .compatible = "realtek,rtd1619-usb2phy", .data = &rtd1619_phy_cfg },
1294 { .compatible = "realtek,rtd1619b-usb2phy", .data = &rtd1619b_phy_cfg },
1303 .name = "rtk-usb2phy",