mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 01:11:14 +00:00
e7bfda2c24
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
170 lines
5.5 KiB
Diff
170 lines
5.5 KiB
Diff
From 28758a9da77954ed323f86123ef448c6a563c037 Mon Sep 17 00:00:00 2001
|
|
From: Florian Fainelli <florian@openwrt.org>
|
|
Date: Mon, 28 Jan 2013 20:06:22 +0100
|
|
Subject: [PATCH 04/11] MIPS: BCM63XX: add OHCI/EHCI configuration bits to
|
|
common USB code
|
|
|
|
This patch updates the common USB code touching the USB private
|
|
registers with the specific bits to properly enable OHCI and EHCI
|
|
controllers on BCM63xx SoCs. As a result we now need to protect access
|
|
to Read Modify Write sequences using a spinlock because we cannot
|
|
guarantee that any of the exposed helper will not be called
|
|
concurrently.
|
|
|
|
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
|
|
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
|
---
|
|
arch/mips/bcm63xx/usb-common.c | 97 ++++++++++++++++++++
|
|
.../include/asm/mach-bcm63xx/bcm63xx_usb_priv.h | 2 +
|
|
2 files changed, 99 insertions(+)
|
|
|
|
--- a/arch/mips/bcm63xx/usb-common.c
|
|
+++ b/arch/mips/bcm63xx/usb-common.c
|
|
@@ -5,10 +5,12 @@
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
|
|
* Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com>
|
|
* Copyright (C) 2012 Broadcom Corporation
|
|
*
|
|
*/
|
|
+#include <linux/spinlock.h>
|
|
#include <linux/export.h>
|
|
|
|
#include <bcm63xx_cpu.h>
|
|
@@ -16,9 +18,14 @@
|
|
#include <bcm63xx_io.h>
|
|
#include <bcm63xx_usb_priv.h>
|
|
|
|
+static DEFINE_SPINLOCK(usb_priv_reg_lock);
|
|
+
|
|
void bcm63xx_usb_priv_select_phy_mode(u32 portmask, bool is_device)
|
|
{
|
|
u32 val;
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
|
|
|
|
val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
|
|
if (is_device) {
|
|
@@ -36,12 +43,17 @@ void bcm63xx_usb_priv_select_phy_mode(u3
|
|
else
|
|
val &= ~USBH_PRIV_SWAP_USBD_MASK;
|
|
bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_SWAP_6368_REG);
|
|
+
|
|
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
|
|
}
|
|
EXPORT_SYMBOL(bcm63xx_usb_priv_select_phy_mode);
|
|
|
|
void bcm63xx_usb_priv_select_pullup(u32 portmask, bool is_on)
|
|
{
|
|
u32 val;
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
|
|
|
|
val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
|
|
if (is_on)
|
|
@@ -49,5 +61,90 @@ void bcm63xx_usb_priv_select_pullup(u32
|
|
else
|
|
val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
|
|
bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG);
|
|
+
|
|
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
|
|
}
|
|
EXPORT_SYMBOL(bcm63xx_usb_priv_select_pullup);
|
|
+
|
|
+/* The following array represents the meaning of the DESC/DATA
|
|
+ * endian swapping with respect to the CPU configured endianness
|
|
+ *
|
|
+ * DATA ENDN mmio descriptor
|
|
+ * 0 0 BE invalid
|
|
+ * 0 1 BE LE
|
|
+ * 1 0 BE BE
|
|
+ * 1 1 BE invalid
|
|
+ *
|
|
+ * Since BCM63XX SoCs are configured to be in big-endian mode
|
|
+ * we want configuration at line 3.
|
|
+ */
|
|
+void bcm63xx_usb_priv_ohci_cfg_set(void)
|
|
+{
|
|
+ u32 reg;
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
|
|
+
|
|
+ if (BCMCPU_IS_6348())
|
|
+ bcm_rset_writel(RSET_OHCI_PRIV, 0, OHCI_PRIV_REG);
|
|
+ else if (BCMCPU_IS_6358()) {
|
|
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG);
|
|
+ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
|
|
+ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6358_REG);
|
|
+ /*
|
|
+ * The magic value comes for the original vendor BSP
|
|
+ * and is needed for USB to work. Datasheet does not
|
|
+ * help, so the magic value is used as-is.
|
|
+ */
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
|
|
+ USBH_PRIV_TEST_6358_REG);
|
|
+
|
|
+ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) {
|
|
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
|
|
+ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
|
|
+ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6368_REG);
|
|
+
|
|
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SETUP_6368_REG);
|
|
+ reg |= USBH_PRIV_SETUP_IOC_MASK;
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SETUP_6368_REG);
|
|
+ }
|
|
+
|
|
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
|
|
+}
|
|
+
|
|
+void bcm63xx_usb_priv_ehci_cfg_set(void)
|
|
+{
|
|
+ u32 reg;
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
|
|
+
|
|
+ if (BCMCPU_IS_6358()) {
|
|
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG);
|
|
+ reg &= ~USBH_PRIV_SWAP_EHCI_ENDN_MASK;
|
|
+ reg |= USBH_PRIV_SWAP_EHCI_DATA_MASK;
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6358_REG);
|
|
+
|
|
+ /*
|
|
+ * The magic value comes for the original vendor BSP
|
|
+ * and is needed for USB to work. Datasheet does not
|
|
+ * help, so the magic value is used as-is.
|
|
+ */
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020,
|
|
+ USBH_PRIV_TEST_6358_REG);
|
|
+
|
|
+ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) {
|
|
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
|
|
+ reg &= ~USBH_PRIV_SWAP_EHCI_ENDN_MASK;
|
|
+ reg |= USBH_PRIV_SWAP_EHCI_DATA_MASK;
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6368_REG);
|
|
+
|
|
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SETUP_6368_REG);
|
|
+ reg |= USBH_PRIV_SETUP_IOC_MASK;
|
|
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SETUP_6368_REG);
|
|
+ }
|
|
+
|
|
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
|
|
+}
|
|
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_usb_priv.h
|
|
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_usb_priv.h
|
|
@@ -5,5 +5,7 @@
|
|
|
|
void bcm63xx_usb_priv_select_phy_mode(u32 portmask, bool is_device);
|
|
void bcm63xx_usb_priv_select_pullup(u32 portmask, bool is_on);
|
|
+void bcm63xx_usb_priv_ohci_cfg_set(void);
|
|
+void bcm63xx_usb_priv_ehci_cfg_set(void);
|
|
|
|
#endif /* BCM63XX_USB_PRIV_H_ */
|