From 2ea771425868525c00a5b56d84f01d44e1c49406 Mon Sep 17 00:00:00 2001 From: William Wu Date: Mon, 24 Feb 2025 17:19:03 +0800 Subject: [PATCH] phy: rockchip: inno-usb2: Add usb2 phy support for rv1126b RV1126B has one USB2.0 PHY with two ports, the OTG port support OTG function and BC1.2, and the Host port only support Host function. The SoC provides USB GRF to control the internal UTMI+ interface and it also provides APB to access the PHY internal registers for the USB HS/FS/LS signal integrity tuning. This patch adds the USB2.0 PHY tuning to improve the signal integrity for RV1126B. 1. Enable pre-emphasis during non-chirp phase. 2. Set HS eye height to 425mv(default is 400mv). 3. Set Rx squelch trigger point configure to 112.5mv. Signed-off-by: William Wu Change-Id: Ief1a0aa532ba6dc6824dce72595bd39d8df8cefe --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 0661c8094bea..f6928c6051cc 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -3259,6 +3259,40 @@ static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy) return ret; } +static int rv1126b_usb2phy_tuning(struct rockchip_usb2phy *rphy) +{ + int ret = 0; + + /* Turn off differential receiver by default to save power */ + phy_clear_bits(rphy->phy_base + 0x0030, BIT(2)); + phy_clear_bits(rphy->phy_base + 0x0430, BIT(2)); + + /* Enable pre-emphasis during non-chirp phase */ + phy_update_bits(rphy->phy_base, GENMASK(2, 0), 0x04); + phy_update_bits(rphy->phy_base + 0x0400, GENMASK(2, 0), 0x04); + + /* Set HS eye height to 425mv(default is 400mv) */ + phy_update_bits(rphy->phy_base + 0x0030, GENMASK(6, 4), (0x05 << 4)); + phy_update_bits(rphy->phy_base + 0x0430, GENMASK(6, 4), (0x05 << 4)); + + /* Set Rx squelch trigger point configure to 112.5mv */ + phy_update_bits(rphy->phy_base + 0x0004, GENMASK(7, 5), (0x00 << 5)); + phy_update_bits(rphy->phy_base + 0x0008, GENMASK(0, 0), (0x00 << 0)); + phy_update_bits(rphy->phy_base + 0x0404, GENMASK(7, 5), (0x00 << 5)); + phy_update_bits(rphy->phy_base + 0x0408, GENMASK(0, 0), (0x00 << 0)); + + /* Set the bvalid filter time to 10ms based on the u2phy grf pclk 100MHz */ + ret |= regmap_write(rphy->grf, 0x10088, FILTER_COUNTER); + + /* Set the id filter time to 10ms based on the u2phy grf pclk 100MHz */ + ret |= regmap_write(rphy->grf, 0x1008c, FILTER_COUNTER); + + /* Enable host port wakeup irq */ + ret |= regmap_write(rphy->grf, 0x000c, 0x80008000); + + return ret; +} + #ifdef CONFIG_PM_SLEEP static int rockchip_usb2phy_pm_suspend(struct device *dev) { @@ -4646,6 +4680,67 @@ static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { { /* sentinel */ } }; +static const struct rockchip_usb2phy_cfg rv1126b_phy_cfgs[] = { + { + .reg = 0x21400000, + .num_ports = 2, + .phy_tuning = rv1126b_usb2phy_tuning, + .vbus_detect = rockchip_usb2phy_vbus_det_control, + .clkout_ctl = { 0x10028, 3, 3, 1, 0 }, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x10020, 8, 0, 0, 0x1d1 }, + .pipe_phystatus = { 0x1003c, 15, 0, 0x1100, 0x0189 }, + .bvalid_det_en = { 0x10074, 2, 2, 0, 1 }, + .bvalid_det_st = { 0x10078, 2, 2, 0, 1 }, + .bvalid_det_clr = { 0x1007c, 2, 2, 0, 1 }, + .bvalid_grf_sel = { 0x10020, 15, 14, 0, 3 }, + .bypass_dm_en = { 0x10028, 1, 1, 0, 1}, + .bypass_sel = { 0x10028, 2, 2, 0, 1}, + .iddig_output = { 0x10020, 10, 10, 0, 1 }, + .iddig_en = { 0x10020, 9, 9, 0, 1 }, + .idfall_det_en = { 0x10074, 5, 5, 0, 1 }, + .idfall_det_st = { 0x10078, 5, 5, 0, 1 }, + .idfall_det_clr = { 0x1007c, 5, 5, 0, 1 }, + .idrise_det_en = { 0x10074, 4, 4, 0, 1 }, + .idrise_det_st = { 0x10078, 4, 4, 0, 1 }, + .idrise_det_clr = { 0x1007c, 4, 4, 0, 1 }, + .ls_det_en = { 0x10074, 0, 0, 0, 1 }, + .ls_det_st = { 0x10078, 0, 0, 0, 1 }, + .ls_det_clr = { 0x1007c, 0, 0, 0, 1 }, + .utmi_avalid = { 0x10110, 1, 1, 0, 1 }, + .utmi_bvalid = { 0x10110, 0, 0, 0, 1 }, + .utmi_iddig = { 0x10110, 6, 6, 0, 1 }, + .utmi_ls = { 0x10110, 5, 4, 0, 1 }, + .vbus_det_en = { 0x003c, 7, 7, 0, 1 }, + .port_ls_filter_con = { 0x10080, 19, 0, 0x30100, 0x20 }, + }, + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0x1001c, 8, 0, 0x1d2, 0x1d1 }, + .ls_det_en = { 0x10090, 0, 0, 0, 1 }, + .ls_det_st = { 0x10094, 0, 0, 0, 1 }, + .ls_det_clr = { 0x10098, 0, 0, 0, 1 }, + .utmi_ls = { 0x10110, 13, 12, 0, 1 }, + .utmi_hstdet = { 0x10110, 15, 15, 0, 1 }, + .port_ls_filter_con = { 0x1009c, 19, 0, 0x30100, 0x20 }, + } + }, + .chg_det = { + .chg_mode = { 0x10020, 8, 0, 0, 0x1d7 }, + .cp_det = { 0x10110, 19, 19, 0, 1 }, + .dcp_det = { 0x10110, 18, 18, 0, 1 }, + .dp_det = { 0x10110, 20, 20, 0, 1 }, + .idm_sink_en = { 0x1002c, 1, 1, 0, 1 }, + .idp_sink_en = { 0x1002c, 0, 0, 0, 1 }, + .idp_src_en = { 0x1002c, 2, 2, 0, 1 }, + .rdm_pdwn_en = { 0x1002c, 3, 3, 0, 1 }, + .vdm_src_en = { 0x1002c, 5, 5, 0, 1 }, + .vdp_src_en = { 0x1002c, 4, 4, 0, 1 }, + }, + }, + { /* sentinel */ } +}; + static const struct of_device_id rockchip_usb2phy_dt_match[] = { #ifdef CONFIG_CPU_PX30 { .compatible = "rockchip,px30-usb2phy", .data = &px30_phy_cfgs }, @@ -4697,6 +4792,9 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = { #endif #ifdef CONFIG_CPU_RV1108 { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, +#endif +#ifdef CONFIG_CPU_RV1126B + { .compatible = "rockchip,rv1126b-usb2phy", .data = &rv1126b_phy_cfgs }, #endif {} };