ARM: tegra3: usb: USB1_UTMIP_XCVR_CFG0_0 value changed
Rakesh Bodla [Thu, 7 Jun 2012 11:59:15 +0000 (16:59 +0530)]
Changed USB1_UTMIP_XCVR_CFG0_0 register value with values
provided by sys-eng
* Implemented algo as described on Bug 974236
* Added variable 'usb_calib_mask' in 'usb platform data' to
make distinction on how many bits to mask in usb_calib_0 fuse

Bug 978870
Bug 972436

Change-Id: I71f27b0cf5ffe33a9896238b01c52650ca632352
Signed-off-by: Rakesh Bodla <rbodla@nvidia.com>
Reviewed-on: http://git-master/r/103308
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

arch/arm/mach-tegra/board-p1852.c
arch/arm/mach-tegra/tegra3_usb_phy.c
include/linux/platform_data/tegra_usb.h

index 1777719..2b1e270 100644 (file)
@@ -367,11 +367,12 @@ static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = {
                .idle_wait_delay = 17,
                .elastic_limit = 16,
                .term_range_adj = 6,
-               .xcvr_setup = 15,
-               .xcvr_setup_offset = 0,
+               .xcvr_setup = 63,
+               .xcvr_setup_offset = 6,
                .xcvr_use_fuses = 1,
                .xcvr_lsfslew = 2,
                .xcvr_lsrslew = 2,
+               .xcvr_use_lsb = 1,
        },
 };
 
@@ -392,11 +393,12 @@ static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = {
                .idle_wait_delay = 17,
                .elastic_limit = 16,
                .term_range_adj = 6,
-               .xcvr_setup = 15,
-               .xcvr_setup_offset = 0,
+               .xcvr_setup = 63,
+               .xcvr_setup_offset = 6,
                .xcvr_use_fuses = 1,
                .xcvr_lsfslew = 2,
                .xcvr_lsrslew = 2,
+               .xcvr_use_lsb = 1,
        },
 };
 
@@ -417,11 +419,12 @@ static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = {
                .idle_wait_delay = 17,
                .elastic_limit = 16,
                .term_range_adj = 6,
-               .xcvr_setup = 8,
-               .xcvr_setup_offset = 0,
+               .xcvr_setup = 63,
+               .xcvr_setup_offset = 6,
                .xcvr_use_fuses = 1,
                .xcvr_lsfslew = 2,
                .xcvr_lsrslew = 2,
+               .xcvr_use_lsb = 1,
        },
 };
 
index 55d4c16..9bddc01 100644 (file)
 #define   UTMIP_PWR(inst)              (1 << (inst))
 
 #define FUSE_USB_CALIB_0               0x1F0
-#define   FUSE_USB_CALIB_XCVR_SETUP(x) (((x) & 0x7F) << 0)
+#define   XCVR_SETUP(x)        (((x) & 0x7F) << 0)
+#define          XCVR_SETUP_LSB_MASK   0xF
+#define          XCVR_SETUP_MSB_MASK   0x70
+#define   XCVR_SETUP_LSB_MAX_VAL       0xF
 
 /* These values (in milli second) are taken from the battery charging spec */
 #define TDP_SRC_ON_MS   100
@@ -1072,19 +1075,24 @@ static unsigned int utmi_phy_xcvr_setup_value(struct tegra_usb_phy *phy)
        DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
 
        if (cfg->xcvr_use_fuses) {
-               val = FUSE_USB_CALIB_XCVR_SETUP(
-                               tegra_fuse_readl(FUSE_USB_CALIB_0));
-               if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET)
-                       val = val + cfg->xcvr_setup_offset;
-
-               if (val > UTMIP_XCVR_SETUP_MAX_VALUE) {
-                       val = UTMIP_XCVR_SETUP_MAX_VALUE;
-                       pr_info("%s: reset XCVR_SETUP to max value\n",
-                                __func__);
-               } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) {
-                       val = UTMIP_XCVR_SETUP_MIN_VALUE;
-                       pr_info("%s: reset XCVR_SETUP to min value\n",
-                                __func__);
+               val = XCVR_SETUP(tegra_fuse_readl(FUSE_USB_CALIB_0));
+               if (cfg->xcvr_use_lsb) {
+                       val = min(((val & XCVR_SETUP_LSB_MASK) + cfg->xcvr_setup_offset),
+                                       XCVR_SETUP_LSB_MAX_VAL);
+                       val |= (cfg->xcvr_setup & XCVR_SETUP_MSB_MASK);
+               } else {
+                       if (cfg->xcvr_setup_offset <= UTMIP_XCVR_MAX_OFFSET)
+                               val = val + cfg->xcvr_setup_offset;
+
+                       if (val > UTMIP_XCVR_SETUP_MAX_VALUE) {
+                               val = UTMIP_XCVR_SETUP_MAX_VALUE;
+                               pr_info("%s: reset XCVR_SETUP to max value\n",
+                                               __func__);
+                       } else if (val < UTMIP_XCVR_SETUP_MIN_VALUE) {
+                               val = UTMIP_XCVR_SETUP_MIN_VALUE;
+                               pr_info("%s: reset XCVR_SETUP to min value\n",
+                                               __func__);
+                       }
                }
        } else {
                val = cfg->xcvr_setup;
@@ -1535,7 +1543,8 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
        val |= UTMIP_XCVR_SETUP_MSB(XCVR_SETUP_MSB_CALIB(phy->utmi_xcvr_setup));
        val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew);
        val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew);
-       val |= UTMIP_XCVR_HSSLEW_MSB(0x8);
+       if (!config->xcvr_use_lsb)
+               val |= UTMIP_XCVR_HSSLEW_MSB(0x8);
        writel(val, base + UTMIP_XCVR_CFG0);
 
        val = readl(base + UTMIP_XCVR_CFG1);
index de17149..9747271 100644 (file)
@@ -47,6 +47,7 @@ struct tegra_utmi_config {
        u8 xcvr_lsfslew;
        u8 xcvr_lsrslew;
        signed char xcvr_setup_offset;
+       u8 xcvr_use_lsb;
        u8 xcvr_use_fuses;
 };