ARM: tegra: usb: AHB prefetch support calls
Krishna Yarlagadda [Mon, 26 Mar 2012 09:25:11 +0000 (14:25 +0530)]
Support for AHB prefetch enable and disable.
These calls are used to avoid memory coherency issues

Bug 921109

Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Reviewed-on: http://git-master/r/92256
(cherry picked from commit c992fdbe0be6e2006d65e67e6eb821a054ad401c)

Change-Id: I1599ee11652b9241b2d05d565289632901f44f44
Reviewed-on: http://git-master/r/93817
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

arch/arm/mach-tegra/include/mach/usb_phy.h
arch/arm/mach-tegra/usb_phy.c

index 36b3575..7e71422 100644 (file)
@@ -163,4 +163,8 @@ int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size);
 
 bool tegra_usb_phy_is_remotewake_detected(struct tegra_usb_phy *phy);
 
+void tegra_usb_phy_memory_prefetch_on(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_memory_prefetch_off(struct tegra_usb_phy *phy);
+
 #endif /* __MACH_USB_PHY_H */
index b078881..0c19c6b 100644 (file)
@@ -614,6 +614,12 @@ static u32 utmip_rctrl_val, utmip_tctrl_val;
 
 #define CONNECT_DETECT_TIMEOUT         25000
 
+#define AHB_MEM_PREFETCH_CFG3          0xe0
+#define AHB_MEM_PREFETCH_CFG4          0xe4
+#define AHB_MEM_PREFETCH_CFG1          0xec
+#define AHB_MEM_PREFETCH_CFG2          0xf0
+#define PREFETCH_ENB                   (1 << 31)
+
 static DEFINE_SPINLOCK(utmip_pad_lock);
 static int utmip_pad_count;
 
@@ -3176,6 +3182,36 @@ int __init tegra_usb_phy_init(struct usb_phy_plat_data *pdata, int size)
        return 0;
 }
 
+void tegra_usb_phy_memory_prefetch_on(struct tegra_usb_phy *phy)
+{
+       void __iomem *ahb_gizmo = IO_ADDRESS(TEGRA_AHB_GIZMO_BASE);
+       unsigned long val;
+
+       if (phy->instance == 0 && phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
+               val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
+               val |= PREFETCH_ENB;
+               writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
+               val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
+               val |= PREFETCH_ENB;
+               writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
+       }
+}
+
+void tegra_usb_phy_memory_prefetch_off(struct tegra_usb_phy *phy)
+{
+       void __iomem *ahb_gizmo = IO_ADDRESS(TEGRA_AHB_GIZMO_BASE);
+       unsigned long val;
+
+       if (phy->instance == 0 && phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
+               val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
+               val &= ~(PREFETCH_ENB);
+               writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG1);
+               val = readl(ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
+               val &= ~(PREFETCH_ENB);
+               writel(val, ahb_gizmo + AHB_MEM_PREFETCH_CFG2);
+       }
+}
+
 /* disable walk and wake events after resume from LP0 */
 bool tegra_usb_phy_is_remotewake_detected(struct tegra_usb_phy *phy)
 {