usb: xhci: tegra: update fuse programming from usb_calib0
Ajay Gupta [Tue, 19 Feb 2013 18:51:32 +0000 (10:51 -0800)]
usb_calib0 fuse description has changed and so driver needs
to program correct value of hs_curr_level for
XUSB_PADCTL_USB2_OTG_PAD1_CTL_0_0

Also reviewed and cleaned up the pad programming both in
Dalmore and Pluto.

Bug 1237038
Bug 1172686

Change-Id: Ib47f20d6aea724d1acdea0241e5598d19dbc4dee
Signed-off-by: Ajay Gupta <ajayg@nvidia.com>
Reviewed-on: http://git-master/r/204775
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>

arch/arm/mach-tegra/board-dalmore.c
arch/arm/mach-tegra/board-pluto.c
drivers/usb/host/xhci-tegra.c
include/linux/platform_data/tegra_xusb.h

index 79a7b8c..7a619a0 100644 (file)
@@ -558,25 +558,24 @@ static void dalmore_usb_init(void)
 }
 
 static struct tegra_xusb_pad_data xusb_padctl_data = {
-       .pad_mux = 0x4,
-       .port_cap = 0x10,
-       .snps_oc_map = 0x1fc,
-       .usb2_oc_map = 0x2f,
-       .ss_port_map = 0x2,
-       .oc_det = 0xb000,
-       .rx_wander = 0xf0,
-       .rx_eq = 0x307000,
-       .cdr_cntl = 0x26000000,
+       .pad_mux = (0x1 << 2),
+       .port_cap = (0x1 << 4),
+       .snps_oc_map = (0x1fc << 0),
+       .usb2_oc_map = (0x2f << 0),
+       .ss_port_map = (0x2 << 0),
+       .oc_det = (0x2c << 10),
+       .rx_wander = (0xf << 4),
+       .rx_eq = (0x3070 << 8),
+       .cdr_cntl = (0x26 << 24),
        .dfe_cntl = 0x002008EE,
-       .otg_pad0_ctl0 = 0xffffffff,
-       .hs_slew = 0xc0,
-       .otg_pad0_ctl1 = 0x0,
-       .otg_pad1_ctl0 = 0xffc7ffff,
-       .otg_pad1_ctl1 = 0x7,
-       .bias_pad_ctl0 = 0,
-       .hsic_pad0_ctl0 = 0xffff00ff,
-       .hsic_pad0_ctl1 = 0xffff00ff,
-       .pmc_value = 0xfff0ffff,
+       .hs_slew = (0x3 << 6),
+       .otg_pad0_ctl0 = (0x7 << 19),
+       .otg_pad1_ctl0 = (0x0 << 19),
+       .otg_pad0_ctl1 = (0x4 << 0),
+       .otg_pad1_ctl1 = (0x3 << 0),
+       .hs_disc_lvl = (0x5 << 2),
+       .hsic_pad0_ctl0 = (0x00 << 8),
+       .hsic_pad0_ctl1 = (0x00 << 8),
 };
 
 static void dalmore_xusb_init(void)
@@ -586,18 +585,21 @@ static void dalmore_xusb_init(void)
        if (usb_port_owner_info & UTMI2_PORT_OWNER_XUSB) {
                u32 usb_calib0 = tegra_fuse_readl(FUSE_SKU_USB_CALIB_0);
 
+               pr_info("dalmore_xusb_init: usb_calib0 = 0x%08x\n", usb_calib0);
                /*
                 * read from usb_calib0 and pass to driver
-                * set HS_CURR_LEVEL = usb_calib0[5:0]
-                * set TERM_RANGE_ADJ = usb_calib0[10:7]
-                * set HS_IREF_CAP = usb_calib0[14:13]
-                * set HS_SQUELCH_LEVEL = usb_calib0[12:11]
+                * set HS_CURR_LEVEL (PAD0)     = usb_calib0[5:0]
+                * set TERM_RANGE_ADJ           = usb_calib0[10:7]
+                * set HS_SQUELCH_LEVEL         = usb_calib0[12:11]
+                * set HS_IREF_CAP              = usb_calib0[14:13]
+                * set HS_CURR_LEVEL (PAD1)     = usb_calib0[20:15]
                 */
 
-               xusb_padctl_data.hs_curr_level = (usb_calib0 >> 0) & 0x3f;
-               xusb_padctl_data.hs_iref_cap = (usb_calib0 >> 13) & 0x3;
+               xusb_padctl_data.hs_curr_level_pad0 = (usb_calib0 >> 0) & 0x3f;
                xusb_padctl_data.hs_term_range_adj = (usb_calib0 >> 7) & 0xf;
                xusb_padctl_data.hs_squelch_level = (usb_calib0 >> 11) & 0x3;
+               xusb_padctl_data.hs_iref_cap = (usb_calib0 >> 13) & 0x3;
+               xusb_padctl_data.hs_curr_level_pad1 = (usb_calib0 >> 15) & 0x3f;
 
                tegra_xhci_device.dev.platform_data = &xusb_padctl_data;
                platform_device_register(&tegra_xhci_device);
index 3b1540b..389fe39 100644 (file)
@@ -1185,21 +1185,24 @@ static void pluto_modem_init(void)
 }
 
 static struct tegra_xusb_pad_data xusb_padctl_data = {
-       .pad_mux = 0x1,
-       .port_cap = 0x1,
-       .snps_oc_map = 0x1ff,
-       .usb2_oc_map = 0x3c,
-       .ss_port_map = 0x2,
-       .oc_det = 0,
-       .rx_wander = 0xf0,
-       .otg_pad0_ctl0 = 0xffc7ffff,
-       .otg_pad0_ctl1 = 0x7,
-       .otg_pad1_ctl0 = 0xffffffff,
-       .otg_pad1_ctl1 = 0,
-       .bias_pad_ctl0 = 0,
-       .hsic_pad0_ctl0 = 0xffff00ff,
-       .hsic_pad0_ctl1 = 0xffff00ff,
-       .pmc_value = 0xfffffff0,
+       .pad_mux = (0x1 << 0),
+       .port_cap = (0x1 << 0),
+       .snps_oc_map = (0x1ff << 0),
+       .usb2_oc_map = (0x3c << 0),
+       .ss_port_map = (0x1 << 0),
+       .oc_det = (0x3f << 10),
+       .rx_wander = (0xf << 4),
+       .rx_eq = (0x3070 << 8),
+       .cdr_cntl = (0x26 << 24),
+       .dfe_cntl = 0x002008EE,
+       .hs_slew = (0x3 << 6),
+       .otg_pad0_ctl0 = (0x0 << 19),
+       .otg_pad1_ctl0 = (0x7 << 19),
+       .otg_pad0_ctl1 = (0x3 << 0),
+       .otg_pad1_ctl1 = (0x4 << 0),
+       .hs_disc_lvl = (0x5 << 2),
+       .hsic_pad0_ctl0 = (0x00 << 8),
+       .hsic_pad0_ctl1 = (0x00 << 8),
 };
 
 static void pluto_xusb_init(void)
@@ -1209,18 +1212,21 @@ static void pluto_xusb_init(void)
        if (usb_port_owner_info & UTMI1_PORT_OWNER_XUSB) {
                u32 usb_calib0 = tegra_fuse_readl(FUSE_SKU_USB_CALIB_0);
 
+               pr_info("dalmore_xusb_init: usb_calib0 = 0x%08x\n", usb_calib0);
                /*
                 * read from usb_calib0 and pass to driver
-                * set HS_CURR_LEVEL = usb_calib0[5:0]
-                * set TERM_RANGE_ADJ = usb_calib0[10:7]
-                * set HS_IREF_CAP = usb_calib0[14:13]
-                * set HS_SQUELCH_LEVEL = usb_calib0[12:11]
+                * set HS_CURR_LEVEL (PAD0)     = usb_calib0[5:0]
+                * set TERM_RANGE_ADJ           = usb_calib0[10:7]
+                * set HS_SQUELCH_LEVEL         = usb_calib0[12:11]
+                * set HS_IREF_CAP              = usb_calib0[14:13]
+                * set HS_CURR_LEVEL (PAD1)     = usb_calib0[20:15]
                 */
 
-               xusb_padctl_data.hs_curr_level = (usb_calib0 >> 0) & 0x3f;
-               xusb_padctl_data.hs_iref_cap = (usb_calib0 >> 13) & 0x3;
+               xusb_padctl_data.hs_curr_level_pad0 = (usb_calib0 >> 0) & 0x3f;
                xusb_padctl_data.hs_term_range_adj = (usb_calib0 >> 7) & 0xf;
                xusb_padctl_data.hs_squelch_level = (usb_calib0 >> 11) & 0x3;
+               xusb_padctl_data.hs_iref_cap = (usb_calib0 >> 13) & 0x3;
+               xusb_padctl_data.hs_curr_level_pad1 = (usb_calib0 >> 15) & 0x3f;
 
                tegra_xhci_device.dev.platform_data = &xusb_padctl_data;
                platform_device_register(&tegra_xhci_device);
index 228d4e9..05815be 100644 (file)
@@ -1543,12 +1543,14 @@ tegra_xhci_padctl_enable_usb_vbus(struct tegra_xhci_hcd *tegra)
         * for USB 2.0 ports owned by XUSB and USB2:
         */
        reg = readl(tegra->padctl_base + SNPS_OC_MAP_0);
+       reg &= ~(0x1ff << 0);
        reg |= xusb_padctl->snps_oc_map;
        writel(reg, tegra->padctl_base + SNPS_OC_MAP_0);
        reg = readl(tegra->padctl_base + SNPS_OC_MAP_0);
 
        reg = readl(tegra->padctl_base + OC_DET_0);
-       reg = xusb_padctl->oc_det;
+       reg &= ~(0x3f << 10);
+       reg |= xusb_padctl->oc_det;
        writel(reg, tegra->padctl_base + OC_DET_0);
 
        /* check if over current seen. Clear if present */
@@ -1565,6 +1567,7 @@ tegra_xhci_padctl_enable_usb_vbus(struct tegra_xhci_hcd *tegra)
        }
 
        reg = readl(tegra->padctl_base + USB2_OC_MAP_0);
+       reg &= ~(0x3f << 0);
        reg |= xusb_padctl->usb2_oc_map;
        writel(reg, tegra->padctl_base + USB2_OC_MAP_0);
 }
@@ -1610,13 +1613,15 @@ tegra_xhci_padctl_portmap_and_caps(struct tegra_xhci_hcd *tegra)
         * FUSE setting read 0x10 for hs_curr_level causing
         * SS/HS/FS hub re-enumeration.
         */
-       xusb_padctl->hs_curr_level = 0x30;
+       xusb_padctl->hs_curr_level_pad0 = 0x30;
+       xusb_padctl->hs_curr_level_pad1 = 0x30;
 
        /* Program the following XUSB PADCTL registers to assign
         * the USB2.0 ports to XUSB or USB2, according to the platform
         * specific configuration
         */
        reg = readl(tegra->padctl_base + USB2_PAD_MUX_0);
+       reg &= ~(0xf << 2);
        reg |= xusb_padctl->pad_mux;
        writel(reg, tegra->padctl_base + USB2_PAD_MUX_0);
 
@@ -1625,6 +1630,7 @@ tegra_xhci_padctl_portmap_and_caps(struct tegra_xhci_hcd *tegra)
         * according to the platform specific configuration:
         */
        reg = readl(tegra->padctl_base + USB2_PORT_CAP_0);
+       reg &= ~((0x3 << 4) | (0x3 << 0));
        reg |= xusb_padctl->port_cap;
        writel(reg, tegra->padctl_base + USB2_PORT_CAP_0);
 
@@ -1637,17 +1643,18 @@ tegra_xhci_padctl_portmap_and_caps(struct tegra_xhci_hcd *tegra)
         * platform specific configuration
         */
        reg = readl(tegra->padctl_base + SS_PORT_MAP_0);
+       reg &= ~(0x7 << 0);
        reg |= xusb_padctl->ss_port_map;
        writel(reg, tegra->padctl_base + SS_PORT_MAP_0);
 
        reg = readl(tegra->padctl_base + IOPHY_USB3_PAD0_CTL_2_0);
-       reg &= ~0xfffffff0; /* clear needed field */
+       reg &= ~0xfffffff0;
        reg |= xusb_padctl->rx_wander | xusb_padctl->rx_eq |
                        xusb_padctl->cdr_cntl;
        writel(reg, tegra->padctl_base + IOPHY_USB3_PAD0_CTL_2_0);
 
        reg = readl(tegra->padctl_base + IOPHY_USB3_PAD1_CTL_2_0);
-       reg &= ~0xfffffff0; /* clear needed field */
+       reg &= ~0xfffffff0;
        reg |= xusb_padctl->rx_wander | xusb_padctl->rx_eq |
                        xusb_padctl->cdr_cntl;
        writel(reg, tegra->padctl_base + IOPHY_USB3_PAD1_CTL_2_0);
@@ -1661,46 +1668,44 @@ tegra_xhci_padctl_portmap_and_caps(struct tegra_xhci_hcd *tegra)
        writel(reg, tegra->padctl_base + IOPHY_USB3_PAD1_CTL_4_0);
 
        reg = readl(tegra->padctl_base + USB2_OTG_PAD0_CTL_0_0);
-       reg &= xusb_padctl->otg_pad0_ctl0;
-       reg |= xusb_padctl->hs_slew;
-       reg &= ~(0x83f << 0);
-       reg |= xusb_padctl->hs_curr_level;
+       reg &= ~((0xfff << 0) | (0x1f << 19));
+       reg |= xusb_padctl->hs_slew
+               | xusb_padctl->hs_curr_level_pad0 | xusb_padctl->otg_pad0_ctl0;
        writel(reg, tegra->padctl_base + USB2_OTG_PAD0_CTL_0_0);
 
        reg = readl(tegra->padctl_base + USB2_OTG_PAD1_CTL_0_0);
-       reg &= xusb_padctl->otg_pad1_ctl0;
-       reg |= xusb_padctl->hs_slew;
-       reg &= ~(0x83f << 0);
-       reg |= xusb_padctl->hs_curr_level;
+       reg &= ~((0xfff << 0) | (0x1f << 19));
+       reg |= xusb_padctl->hs_slew
+               | xusb_padctl->hs_curr_level_pad1 | xusb_padctl->otg_pad1_ctl0;
        writel(reg, tegra->padctl_base + USB2_OTG_PAD1_CTL_0_0);
 
        reg = readl(tegra->padctl_base + USB2_OTG_PAD0_CTL_1_0);
-       reg ^= xusb_padctl->otg_pad0_ctl1;
-       reg &= ~((0x3 << 9) | (0xf << 3));
-       reg |= (xusb_padctl->hs_iref_cap << 9) |
-                                       (xusb_padctl->hs_term_range_adj << 3);
+       reg &= ~((0x7 << 0) | (0x3 << 9) | (0xf << 3));
+       reg |= (xusb_padctl->otg_pad0_ctl1 << 0)
+               | (xusb_padctl->hs_iref_cap << 9)
+               | (xusb_padctl->hs_term_range_adj << 3);
        writel(reg, tegra->padctl_base + USB2_OTG_PAD0_CTL_1_0);
 
        reg = readl(tegra->padctl_base + USB2_OTG_PAD1_CTL_1_0);
-       reg ^= xusb_padctl->otg_pad1_ctl1;
-       reg &= ~((0x3 << 9) | (0xf << 3));
-       reg |= (xusb_padctl->hs_iref_cap << 9) |
-                                       (xusb_padctl->hs_term_range_adj << 3);
+       reg &= ~((0x7 << 0) | (0xf << 3) | (0x3 << 9));
+       reg |= (xusb_padctl->otg_pad1_ctl1 << 0)
+               | (xusb_padctl->hs_term_range_adj << 3)
+               | (xusb_padctl->hs_iref_cap << 9);
        writel(reg, tegra->padctl_base + USB2_OTG_PAD1_CTL_1_0);
 
        reg = readl(tegra->padctl_base + USB2_BIAS_PAD_CTL_0_0);
-       reg &= xusb_padctl->bias_pad_ctl0;
-       reg |= HS_DISCON_LEVEL(5);
-       reg &= ~(0x3 << 0);
-       reg |= xusb_padctl->hs_squelch_level;
+       reg &= ~((0x1f << 0) | (0x3 << 12));
+       reg |= xusb_padctl->hs_squelch_level | xusb_padctl->hs_disc_lvl;
        writel(reg, tegra->padctl_base + USB2_BIAS_PAD_CTL_0_0);
 
        reg = readl(tegra->padctl_base + HSIC_PAD0_CTL_0_0);
-       reg &= xusb_padctl->hsic_pad0_ctl0;
+       reg &= ~(0xff << 8);
+       reg |= xusb_padctl->hsic_pad0_ctl0;
        writel(reg, tegra->padctl_base + HSIC_PAD0_CTL_0_0);
 
        reg = readl(tegra->padctl_base + HSIC_PAD1_CTL_0_0);
-       reg &= xusb_padctl->hsic_pad0_ctl1;
+       reg &= ~(0xff << 8);
+       reg |= xusb_padctl->hsic_pad0_ctl1;
        writel(reg, tegra->padctl_base + HSIC_PAD1_CTL_0_0);
 
        utmip_biaspd_workaround(tegra);
index 118c893..e173571 100644 (file)
@@ -30,18 +30,18 @@ struct tegra_xusb_pad_data {
        u32 rx_eq;
        u32 cdr_cntl;
        u32 dfe_cntl;
-       u32 otg_pad0_ctl0;
        u32 hs_slew;
-       u32 hs_curr_level;
+       u32 hs_curr_level_pad0;
+       u32 hs_curr_level_pad1;
        u32 hs_iref_cap;
        u32 hs_term_range_adj;
        u32 hs_squelch_level;
-       u32 otg_pad0_ctl1;
+       u32 otg_pad0_ctl0;
        u32 otg_pad1_ctl0;
+       u32 otg_pad0_ctl1;
        u32 otg_pad1_ctl1;
-       u32 bias_pad_ctl0;
+       u32 hs_disc_lvl;
        u32 hsic_pad0_ctl0;
        u32 hsic_pad0_ctl1;
-       u32 pmc_value;
 };
 #endif /* _TEGRA_XUSB_H_ */