diff options
Diffstat (limited to 'drivers/usb/phy')
| -rw-r--r-- | drivers/usb/phy/phy-tegra-usb.c | 81 |
1 files changed, 63 insertions, 18 deletions
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 1ad184af7601..3bfb3d1957c1 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c | |||
| @@ -99,11 +99,15 @@ | |||
| 99 | #define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) | 99 | #define UTMIP_FORCE_PD2_POWERDOWN (1 << 16) |
| 100 | #define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) | 100 | #define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18) |
| 101 | #define UTMIP_XCVR_LSBIAS_SEL (1 << 21) | 101 | #define UTMIP_XCVR_LSBIAS_SEL (1 << 21) |
| 102 | #define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25) | 102 | #define UTMIP_XCVR_HSSLEW(x) (((x) & 0x3) << 4) |
| 103 | #define UTMIP_XCVR_HSSLEW_MSB(x) ((((x) & 0x1fc) >> 2) << 25) | ||
| 103 | 104 | ||
| 104 | #define UTMIP_BIAS_CFG0 0x80c | 105 | #define UTMIP_BIAS_CFG0 0x80c |
| 105 | #define UTMIP_OTGPD (1 << 11) | 106 | #define UTMIP_OTGPD (1 << 11) |
| 106 | #define UTMIP_BIASPD (1 << 10) | 107 | #define UTMIP_BIASPD (1 << 10) |
| 108 | #define UTMIP_HSSQUELCH_LEVEL(x) (((x) & 0x3) << 0) | ||
| 109 | #define UTMIP_HSDISCON_LEVEL(x) (((x) & 0x3) << 2) | ||
| 110 | #define UTMIP_HSDISCON_LEVEL_MSB(x) ((((x) & 0x4) >> 2) << 24) | ||
| 107 | 111 | ||
| 108 | #define UTMIP_HSRX_CFG0 0x810 | 112 | #define UTMIP_HSRX_CFG0 0x810 |
| 109 | #define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) | 113 | #define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10) |
| @@ -255,6 +259,7 @@ static void utmip_pad_power_on(struct tegra_usb_phy *phy) | |||
| 255 | { | 259 | { |
| 256 | unsigned long val, flags; | 260 | unsigned long val, flags; |
| 257 | void __iomem *base = phy->pad_regs; | 261 | void __iomem *base = phy->pad_regs; |
| 262 | struct tegra_utmip_config *config = phy->config; | ||
| 258 | 263 | ||
| 259 | clk_prepare_enable(phy->pad_clk); | 264 | clk_prepare_enable(phy->pad_clk); |
| 260 | 265 | ||
| @@ -263,6 +268,16 @@ static void utmip_pad_power_on(struct tegra_usb_phy *phy) | |||
| 263 | if (utmip_pad_count++ == 0) { | 268 | if (utmip_pad_count++ == 0) { |
| 264 | val = readl(base + UTMIP_BIAS_CFG0); | 269 | val = readl(base + UTMIP_BIAS_CFG0); |
| 265 | val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); | 270 | val &= ~(UTMIP_OTGPD | UTMIP_BIASPD); |
| 271 | |||
| 272 | if (phy->soc_config->requires_extra_tuning_parameters) { | ||
| 273 | val &= ~(UTMIP_HSSQUELCH_LEVEL(~0) | | ||
| 274 | UTMIP_HSDISCON_LEVEL(~0) | | ||
| 275 | UTMIP_HSDISCON_LEVEL_MSB(~0)); | ||
| 276 | |||
| 277 | val |= UTMIP_HSSQUELCH_LEVEL(config->hssquelch_level); | ||
| 278 | val |= UTMIP_HSDISCON_LEVEL(config->hsdiscon_level); | ||
| 279 | val |= UTMIP_HSDISCON_LEVEL_MSB(config->hsdiscon_level); | ||
| 280 | } | ||
| 266 | writel(val, base + UTMIP_BIAS_CFG0); | 281 | writel(val, base + UTMIP_BIAS_CFG0); |
| 267 | } | 282 | } |
| 268 | 283 | ||
| @@ -431,12 +446,20 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) | |||
| 431 | val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | | 446 | val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | |
| 432 | UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_LSBIAS_SEL | | 447 | UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_LSBIAS_SEL | |
| 433 | UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_SETUP_MSB(~0) | | 448 | UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_SETUP_MSB(~0) | |
| 434 | UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) | | 449 | UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0)); |
| 435 | UTMIP_XCVR_HSSLEW_MSB(~0)); | 450 | |
| 436 | val |= UTMIP_XCVR_SETUP(config->xcvr_setup); | 451 | if (!config->xcvr_setup_use_fuses) { |
| 437 | val |= UTMIP_XCVR_SETUP_MSB(config->xcvr_setup); | 452 | val |= UTMIP_XCVR_SETUP(config->xcvr_setup); |
| 453 | val |= UTMIP_XCVR_SETUP_MSB(config->xcvr_setup); | ||
| 454 | } | ||
| 438 | val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); | 455 | val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew); |
| 439 | val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); | 456 | val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew); |
| 457 | |||
| 458 | if (phy->soc_config->requires_extra_tuning_parameters) { | ||
| 459 | val &= ~(UTMIP_XCVR_HSSLEW(~0) | UTMIP_XCVR_HSSLEW_MSB(~0)); | ||
| 460 | val |= UTMIP_XCVR_HSSLEW(config->xcvr_hsslew); | ||
| 461 | val |= UTMIP_XCVR_HSSLEW_MSB(config->xcvr_hsslew); | ||
| 462 | } | ||
| 440 | writel(val, base + UTMIP_XCVR_CFG0); | 463 | writel(val, base + UTMIP_XCVR_CFG0); |
| 441 | 464 | ||
| 442 | val = readl(base + UTMIP_XCVR_CFG1); | 465 | val = readl(base + UTMIP_XCVR_CFG1); |
| @@ -450,14 +473,14 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) | |||
| 450 | val |= UTMIP_BIAS_PDTRK_COUNT(0x5); | 473 | val |= UTMIP_BIAS_PDTRK_COUNT(0x5); |
| 451 | writel(val, base + UTMIP_BIAS_CFG1); | 474 | writel(val, base + UTMIP_BIAS_CFG1); |
| 452 | 475 | ||
| 453 | if (phy->is_legacy_phy) { | 476 | val = readl(base + UTMIP_SPARE_CFG0); |
| 454 | val = readl(base + UTMIP_SPARE_CFG0); | 477 | if (config->xcvr_setup_use_fuses) |
| 455 | if (phy->mode == USB_DR_MODE_PERIPHERAL) | 478 | val |= FUSE_SETUP_SEL; |
| 456 | val &= ~FUSE_SETUP_SEL; | 479 | else |
| 457 | else | 480 | val &= ~FUSE_SETUP_SEL; |
| 458 | val |= FUSE_SETUP_SEL; | 481 | writel(val, base + UTMIP_SPARE_CFG0); |
| 459 | writel(val, base + UTMIP_SPARE_CFG0); | 482 | |
| 460 | } else { | 483 | if (!phy->is_legacy_phy) { |
| 461 | val = readl(base + USB_SUSP_CTRL); | 484 | val = readl(base + USB_SUSP_CTRL); |
| 462 | val |= UTMIP_PHY_ENABLE; | 485 | val |= UTMIP_PHY_ENABLE; |
| 463 | writel(val, base + USB_SUSP_CTRL); | 486 | writel(val, base + USB_SUSP_CTRL); |
| @@ -888,11 +911,6 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, | |||
| 888 | if (err < 0) | 911 | if (err < 0) |
| 889 | return err; | 912 | return err; |
| 890 | 913 | ||
| 891 | err = read_utmi_param(pdev, "nvidia,xcvr-setup", | ||
| 892 | &config->xcvr_setup); | ||
| 893 | if (err < 0) | ||
| 894 | return err; | ||
| 895 | |||
| 896 | err = read_utmi_param(pdev, "nvidia,xcvr-lsfslew", | 914 | err = read_utmi_param(pdev, "nvidia,xcvr-lsfslew", |
| 897 | &config->xcvr_lsfslew); | 915 | &config->xcvr_lsfslew); |
| 898 | if (err < 0) | 916 | if (err < 0) |
| @@ -903,6 +921,33 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, | |||
| 903 | if (err < 0) | 921 | if (err < 0) |
| 904 | return err; | 922 | return err; |
| 905 | 923 | ||
| 924 | if (tegra_phy->soc_config->requires_extra_tuning_parameters) { | ||
| 925 | err = read_utmi_param(pdev, "nvidia,xcvr-hsslew", | ||
| 926 | &config->xcvr_hsslew); | ||
| 927 | if (err < 0) | ||
| 928 | return err; | ||
| 929 | |||
| 930 | err = read_utmi_param(pdev, "nvidia,hssquelch-level", | ||
| 931 | &config->hssquelch_level); | ||
| 932 | if (err < 0) | ||
| 933 | return err; | ||
| 934 | |||
| 935 | err = read_utmi_param(pdev, "nvidia,hsdiscon-level", | ||
| 936 | &config->hsdiscon_level); | ||
| 937 | if (err < 0) | ||
| 938 | return err; | ||
| 939 | } | ||
| 940 | |||
| 941 | config->xcvr_setup_use_fuses = of_property_read_bool( | ||
| 942 | pdev->dev.of_node, "nvidia,xcvr-setup-use-fuses"); | ||
| 943 | |||
| 944 | if (!config->xcvr_setup_use_fuses) { | ||
| 945 | err = read_utmi_param(pdev, "nvidia,xcvr-setup", | ||
| 946 | &config->xcvr_setup); | ||
| 947 | if (err < 0) | ||
| 948 | return err; | ||
| 949 | } | ||
| 950 | |||
| 906 | return 0; | 951 | return 0; |
| 907 | } | 952 | } |
| 908 | 953 | ||
