From: Minkyu Kang <mk7.kang@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 5/8] usb: xhci-exynos5: Add support for multiple USB 3.0 controllers
Date: Tue, 07 Jan 2014 14:30:49 +0900 [thread overview]
Message-ID: <52CB9109.1040907@samsung.com> (raw)
In-Reply-To: <1389000583-20758-6-git-send-email-gautam.vivek@samsung.com>
Dear Vivek Gautam,
On 06/01/14 18:29, Vivek Gautam wrote:
> Add required support to use multiple USB 3.0 controllers available
> on exynos5420 SoC.
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> ---
> arch/arm/cpu/armv7/exynos/power.c | 18 ++++--
> arch/arm/include/asm/arch-exynos/cpu.h | 10 ++++
> arch/arm/include/asm/arch-exynos/power.h | 2 +-
> drivers/usb/host/xhci-exynos5.c | 91 +++++++++++++++++++++---------
> drivers/usb/host/xhci.c | 4 --
> drivers/usb/host/xhci.h | 4 ++
> 6 files changed, 91 insertions(+), 38 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c
> index 563abd7..0f8aa98 100644
> --- a/arch/arm/cpu/armv7/exynos/power.c
> +++ b/arch/arm/cpu/armv7/exynos/power.c
> @@ -59,26 +59,34 @@ void set_usbhost_phy_ctrl(unsigned int enable)
> exynos5_set_usbhost_phy_ctrl(enable);
> }
>
> -static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable)
> +static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable, int dev_index)
> {
> struct exynos5_power *power =
> (struct exynos5_power *)samsung_get_base_power();
>
> + /*
> + * Assuming here that the DRD_PHY_CONTROL registers
> + * are contiguous, so that :
> + * addressof(DRD_PHY1_CONTROL) = addressof(DRD_PHY_CONTROL) + 0x4;
> + * which is the case with exynos5420.
> + * For exynos5250 this should work out of box, since dev_index will
> + * always be '0' in that case
> + */
> if (enable) {
> /* Enabling USBDRD_PHY */
> - setbits_le32(&power->usbdrd_phy_control,
> + setbits_le32(&power->usbdrd_phy_control + dev_index,
> POWER_USB_DRD_PHY_CTRL_EN);
> } else {
> /* Disabling USBDRD_PHY */
> - clrbits_le32(&power->usbdrd_phy_control,
> + clrbits_le32(&power->usbdrd_phy_control + dev_index,
> POWER_USB_DRD_PHY_CTRL_EN);
> }
> }
>
> -void set_usbdrd_phy_ctrl(unsigned int enable)
> +void set_usbdrd_phy_ctrl(unsigned int enable, int dev_index)
> {
> if (cpu_is_exynos5())
> - exynos5_set_usbdrd_phy_ctrl(enable);
> + exynos5_set_usbdrd_phy_ctrl(enable, dev_index);
> }
>
> static void exynos5_dp_phy_control(unsigned int enable)
> diff --git a/arch/arm/include/asm/arch-exynos/cpu.h b/arch/arm/include/asm/arch-exynos/cpu.h
> index 718940b..d93cba9 100644
> --- a/arch/arm/include/asm/arch-exynos/cpu.h
> +++ b/arch/arm/include/asm/arch-exynos/cpu.h
> @@ -54,6 +54,8 @@
> #define EXYNOS4_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE
> #define EXYNOS4_USB3PHY_BASE DEVICE_NOT_AVAILABLE
> #define EXYNOS4_DMC_TZASC_BASE DEVICE_NOT_AVAILABLE
> +#define EXYNOS4_USB_HOST_XHCI_1_BASE DEVICE_NOT_AVAILABLE
> +#define EXYNOS4_USB3PHY_1_BASE DEVICE_NOT_AVAILABLE
>
> /* EXYNOS4X12 */
> #define EXYNOS4X12_GPIO_PART3_BASE 0x03860000
> @@ -93,6 +95,8 @@
> #define EXYNOS4X12_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE
> #define EXYNOS4X12_USB3PHY_BASE DEVICE_NOT_AVAILABLE
> #define EXYNOS4X12_DMC_TZASC_BASE DEVICE_NOT_AVAILABLE
> +#define EXYNOS4X12_USB_HOST_XHCI_1_BASE DEVICE_NOT_AVAILABLE
> +#define EXYNOS4X12_USB3PHY_1_BASE DEVICE_NOT_AVAILABLE
>
> /* EXYNOS5 */
> #define EXYNOS5_I2C_SPACING 0x10000
> @@ -132,6 +136,8 @@
> #define EXYNOS5_ADC_BASE DEVICE_NOT_AVAILABLE
> #define EXYNOS5_MODEM_BASE DEVICE_NOT_AVAILABLE
> #define EXYNOS5_DMC_TZASC_BASE DEVICE_NOT_AVAILABLE
> +#define EXYNOS5_USB_HOST_XHCI_1_BASE DEVICE_NOT_AVAILABLE
> +#define EXYNOS5_USB3PHY_1_BASE DEVICE_NOT_AVAILABLE
>
> /* EXYNOS5420 */
> #define EXYNOS5420_AUDIOSS_BASE 0x03810000
> @@ -153,6 +159,8 @@
> #define EXYNOS5420_USBPHY_BASE 0x12130000
> #define EXYNOS5420_MMC_BASE 0x12200000
> #define EXYNOS5420_SROMC_BASE 0x12250000
> +#define EXYNOS5420_USB_HOST_XHCI_1_BASE 0x12400000
> +#define EXYNOS5420_USB3PHY_1_BASE 0x12500000
No. we don't have to add phy_1 and xhci_1.
It looks weird.
please access phy1 and xhci1 by offset.
> #define EXYNOS5420_UART_BASE 0x12C00000
> #define EXYNOS5420_I2C_BASE 0x12C60000
> #define EXYNOS5420_I2C_8910_BASE 0x12E00000
> @@ -276,8 +284,10 @@ SAMSUNG_BASE(timer, PWMTIMER_BASE)
> SAMSUNG_BASE(uart, UART_BASE)
> SAMSUNG_BASE(usb_phy, USBPHY_BASE)
> SAMSUNG_BASE(usb3_phy, USB3PHY_BASE)
> +SAMSUNG_BASE(usb3_phy_1, USB3PHY_1_BASE)
> SAMSUNG_BASE(usb_ehci, USB_HOST_EHCI_BASE)
> SAMSUNG_BASE(usb_xhci, USB_HOST_XHCI_BASE)
> +SAMSUNG_BASE(usb_xhci_1, USB_HOST_XHCI_1_BASE)
> SAMSUNG_BASE(usb_otg, USBOTG_BASE)
> SAMSUNG_BASE(watchdog, WATCHDOG_BASE)
> SAMSUNG_BASE(power, POWER_BASE)
> diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h
> index c9609a2..c3f2ef0 100644
> --- a/arch/arm/include/asm/arch-exynos/power.h
> +++ b/arch/arm/include/asm/arch-exynos/power.h
> @@ -1684,7 +1684,7 @@ void set_hw_thermal_trip(void);
> #define POWER_USB_HOST_PHY_CTRL_EN (1 << 0)
> #define POWER_USB_HOST_PHY_CTRL_DISABLE (0 << 0)
>
> -void set_usbdrd_phy_ctrl(unsigned int enable);
> +void set_usbdrd_phy_ctrl(unsigned int enable, int dev_index);
>
> #define POWER_USB_DRD_PHY_CTRL_EN (1 << 0)
> #define POWER_USB_DRD_PHY_CTRL_DISABLE (0 << 0)
> diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
> index 1146d10..b5fce40 100644
> --- a/drivers/usb/host/xhci-exynos5.c
> +++ b/drivers/usb/host/xhci-exynos5.c
> @@ -43,18 +43,30 @@ struct exynos_xhci {
> struct fdt_gpio_state vbus_gpio;
> };
>
> -static struct exynos_xhci exynos;
> +static struct exynos_xhci reg_bases[CONFIG_USB_MAX_CONTROLLER_COUNT];
>
> #ifdef CONFIG_OF_CONTROL
> -static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
> +static int exynos_usb3_parse_dt(const void *blob,
> + struct exynos_xhci *base,
> + int index)
> {
> fdt_addr_t addr;
> - unsigned int node;
> - int depth;
> + int depth, count;
> + unsigned int node = 0;
= 0; unnecessary.
> + int nodes[CONFIG_USB_MAX_CONTROLLER_COUNT];
> +
> + /* First find all the compatible nodes */
> + count = fdtdec_find_aliases_for_id(blob, "xhci",
> + COMPAT_SAMSUNG_EXYNOS5_XHCI, nodes,
> + CONFIG_USB_MAX_CONTROLLER_COUNT);
> + if (count < 0) {
> + printf("XHCI: Can't get device node for xhci\n");
> + return -ENODEV;
> + }
>
> - node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_XHCI);
> + node = nodes[index];
> if (node <= 0) {
> - debug("XHCI: Can't get device node for xhci\n");
> + printf("XHCI: Can't get device node for xhci\n");
> return -ENODEV;
> }
>
> @@ -66,10 +78,10 @@ static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
> debug("Can't get the XHCI register base address\n");
> return -ENXIO;
> }
> - exynos->hcd = (struct xhci_hccr *)addr;
> + base->hcd = (struct xhci_hccr *)addr;
>
> /* Vbus gpio */
> - fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio);
> + fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &base->vbus_gpio);
>
> depth = 0;
> node = fdtdec_next_compatible_subnode(blob, node,
> @@ -82,9 +94,9 @@ static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
> /*
> * Get the base address for usbphy from the device node
> */
> - exynos->usb3_phy = (struct exynos_usb3_phy *)fdtdec_get_addr(blob, node,
> + base->usb3_phy = (struct exynos_usb3_phy *)fdtdec_get_addr(blob, node,
> "reg");
> - if (exynos->usb3_phy == NULL) {
> + if (base->usb3_phy == NULL) {
> debug("Can't get the usbphy register address\n");
> return -ENXIO;
> }
> @@ -97,9 +109,6 @@ static void exynos5_usb3_phy_init(struct exynos_usb3_phy *phy)
> {
> u32 reg;
>
> - /* enabling usb_drd phy */
> - set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_EN);
> -
> /* Reset USB 3.0 PHY */
> writel(0x0, &phy->phy_reg0);
>
> @@ -176,9 +185,6 @@ static void exynos5_usb3_phy_exit(struct exynos_usb3_phy *phy)
> setbits_le32(&phy->phy_test,
> PHYTEST_POWERDOWN_SSP |
> PHYTEST_POWERDOWN_HSP);
> -
> - /* disabling usb_drd phy */
> - set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_DISABLE);
> }
>
> void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
> @@ -259,41 +265,64 @@ static int dwc3_core_init(struct dwc3 *dwc3_reg)
> return 0;
> }
>
> -static int exynos_xhci_core_init(struct exynos_xhci *exynos)
> +static int exynos_xhci_core_init(struct exynos_xhci *base)
> {
> int ret;
>
> - exynos5_usb3_phy_init(exynos->usb3_phy);
> + exynos5_usb3_phy_init(base->usb3_phy);
>
> - ret = dwc3_core_init(exynos->dwc3_reg);
> + ret = dwc3_core_init(base->dwc3_reg);
> if (ret) {
> debug("failed to initialize core\n");
> return -EINVAL;
> }
>
> - /* We are hard-coding DWC3 core to Host Mode */
> - dwc3_set_mode(exynos->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
> + /*
> + * TODO: We are hard-coding DWC3 core to Host Mode;
> + * when we have complete DWC3 support we may want to
> + * have both device as well as host mode, so this will
> + * vanish off then.
> + */
> + dwc3_set_mode(base->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
>
> return 0;
> }
>
> -static void exynos_xhci_core_exit(struct exynos_xhci *exynos)
> +static void exynos_xhci_core_exit(struct exynos_xhci *base)
> {
> - exynos5_usb3_phy_exit(exynos->usb3_phy);
> + exynos5_usb3_phy_exit(base->usb3_phy);
> }
>
> int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
> {
> - struct exynos_xhci *ctx = &exynos;
> + struct exynos_xhci *ctx = ®_bases[index];
> int ret;
>
> #ifdef CONFIG_OF_CONTROL
> - exynos_usb3_parse_dt(gd->fdt_blob, ctx);
> + exynos_usb3_parse_dt(gd->fdt_blob, ctx, index);
> #else
> - ctx->usb3_phy = (struct exynos_usb3_phy *)samsung_get_base_usb3_phy();
> - ctx->hcd = (struct xhci_hccr *)samsung_get_base_usb_xhci();
> + /*
> + * right now we only have h/w with 2 controllers, so limiting the
> + * index to two here: either 0 or 1.
> + */
> + if (index == 0) {
> + ctx->usb3_phy = (struct exynos_usb3_phy *)
> + samsung_get_base_usb3_phy();
> + ctx->hcd = (struct xhci_hccr *)
> + samsung_get_base_usb_xhci();
> + } else if (index == 1) {
> + ctx->usb3_phy = (struct exynos_usb3_phy *)
> + samsung_get_base_usb3_phy_1();
> + ctx->hcd = (struct xhci_hccr *)
> + samsung_get_base_usb_xhci_1();
> + }
> #endif
>
> + if (!ctx->hcd || !ctx->usb3_phy) {
> + printf("XHCI: Unable to find Host controller\n");
> + return -ENODEV;
> + }
> +
> ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
>
> #ifdef CONFIG_OF_CONTROL
> @@ -302,6 +331,9 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
> gpio_direction_output(ctx->vbus_gpio.gpio, 1);
> #endif
>
> + /* Power-on usb_drd phy */
> + set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_EN, index);
> +
> ret = exynos_xhci_core_init(ctx);
> if (ret) {
> puts("XHCI: failed to initialize controller\n");
> @@ -321,7 +353,10 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
>
> void xhci_hcd_stop(int index)
> {
> - struct exynos_xhci *ctx = &exynos;
> + struct exynos_xhci *ctx = ®_bases[index];
>
> exynos_xhci_core_exit(ctx);
> +
> + /* Power-off usb_drd phy */
> + set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_DISABLE, index);
> }
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index d1c2e5c..24175e6 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -30,10 +30,6 @@
> #include <asm-generic/errno.h>
> #include "xhci.h"
>
> -#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
> -#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
> -#endif
> -
> static struct descriptor {
> struct usb_hub_descriptor hub;
> struct usb_device_descriptor device;
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index ceb1573..612bf79 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -21,6 +21,10 @@
> #include <asm/io.h>
> #include <linux/list.h>
>
> +#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
> +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
> +#endif
> +
> #define upper_32_bits(n) (u32)((n) >> 32)
> #define lower_32_bits(n) (u32)(n)
>
>
Thanks,
Minkyu Kang.
next prev parent reply other threads:[~2014-01-07 5:30 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-06 9:29 [U-Boot] [PATCH 0/8] Exynos5420: Add support for XHCI controller Vivek Gautam
2014-01-06 9:29 ` [U-Boot] [PATCH 1/8] arm: exynos5420: Fix base address for USBPHY Vivek Gautam
2014-01-06 15:47 ` Marek Vasut
2014-01-06 9:29 ` [U-Boot] [PATCH 2/8] arm: exynos5420: Add base addresses for USB 3.0 Vivek Gautam
2014-01-06 15:47 ` Marek Vasut
2014-01-06 9:29 ` [U-Boot] [PATCH 3/8] dts: exynos5250: Remove explicit device node of 'xhci' Vivek Gautam
2014-01-06 15:47 ` Marek Vasut
2014-01-06 9:29 ` [U-Boot] [PATCH 4/8] config: exynos5: Enable XHCI on all Exynos5 systems Vivek Gautam
2014-01-06 15:47 ` Marek Vasut
2014-01-06 9:29 ` [U-Boot] [PATCH 5/8] usb: xhci-exynos5: Add support for multiple USB 3.0 controllers Vivek Gautam
2014-01-06 15:51 ` Marek Vasut
2014-01-07 9:48 ` Vivek Gautam
2014-01-07 5:30 ` Minkyu Kang [this message]
2014-01-07 9:15 ` Vivek Gautam
2014-01-07 10:59 ` Marek Vasut
2014-01-07 11:41 ` Vivek Gautam
2014-01-06 9:29 ` [U-Boot] [PATCH 6/8] dts: exynos5420: Move device node for xhci 2nd controller Vivek Gautam
2014-01-06 15:51 ` Marek Vasut
2014-01-06 9:29 ` [U-Boot] [PATCH 7/8] smdk5420: Correct the vbus gpio configuration for USB controller Vivek Gautam
2014-01-06 15:52 ` Marek Vasut
2014-01-07 6:37 ` Vivek Gautam
2014-01-07 7:49 ` Marek Vasut
2014-01-07 9:03 ` Vivek Gautam
2014-01-07 9:15 ` Marek Vasut
2014-01-06 9:29 ` [U-Boot] [PATCH 8/8] config: smdk5420: Enable support for multiple XHCI controllers Vivek Gautam
2014-01-06 15:54 ` Marek Vasut
2014-01-07 8:55 ` Vivek Gautam
2014-01-07 9:14 ` Marek Vasut
2014-01-07 9:37 ` Vivek Gautam
2014-01-07 11:09 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52CB9109.1040907@samsung.com \
--to=mk7.kang@samsung.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.