From: Kever Yang <kever.yang@rock-chips.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 1/7] usb: xhci-rockchip: add rockchip dwc3 controller driver
Date: Wed, 24 Aug 2016 11:34:43 +0800 [thread overview]
Message-ID: <57BD15D3.3030903@rock-chips.com> (raw)
In-Reply-To: <CAPnjgZ1z-1QSnTbAdDkpLOWRqFt3ntZXgf53oG2FXh5VEM2g_g@mail.gmail.com>
Hi Simon,
On 08/22/2016 12:20 PM, Simon Glass wrote:
> Hi Kever,
>
> On 19 August 2016 at 01:19, Kever Yang <kever.yang@rock-chips.com> wrote:
>> From: MengDongyang <daniel.meng@rock-chips.com>
>>
>> This patch add support for rockchip dwc3 controller, which corresponding
>> to the two type-C port on rk3399 evb.
>> Only support usb2.0 currently for we have not enable the usb3.0 phy
>> driver and PD(fusb302) driver.
>>
>> Signed-off-by: MengDongyang <daniel.meng@rock-chips.com>
>> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
>> ---
>>
>> Changes in v2:
>> - update for comments from Marek
>>
>> drivers/usb/host/Makefile | 1 +
>> drivers/usb/host/xhci-rockchip.c | 227 +++++++++++++++++++++++++++++++++++++++
>> include/linux/usb/dwc3.h | 9 ++
>> 3 files changed, 237 insertions(+)
>> create mode 100644 drivers/usb/host/xhci-rockchip.c
>>
>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>> index 620d114..fdefcf6 100644
>> --- a/drivers/usb/host/Makefile
>> +++ b/drivers/usb/host/Makefile
>> @@ -56,6 +56,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>> # xhci
>> obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>> obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
>> +obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
>> obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
>> obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
>> obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
>> diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
>> new file mode 100644
>> index 0000000..baf6b6e
>> --- /dev/null
>> +++ b/drivers/usb/host/xhci-rockchip.c
>> @@ -0,0 +1,227 @@
>> +/*
>> + * Copyright (c) 2016 Rockchip, Inc.
>> + * Authors: Daniel Meng <daniel.meng@rock-chips.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <fdtdec.h>
>> +#include <libfdt.h>
>> +#include <malloc.h>
>> +#include <usb.h>
>> +#include <watchdog.h>
>> +#include <asm/gpio.h>
>> +#include <asm-generic/errno.h>
>> +#include <linux/compat.h>
>> +#include <linux/usb/dwc3.h>
>> +
>> +#include "xhci.h"
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct rockchip_xhci_platdata {
>> + fdt_addr_t hcd_base;
>> + fdt_addr_t phy_base;
>> + struct gpio_desc vbus_gpio;
>> +};
>> +
>> +/*
>> + * Contains pointers to register base addresses
>> + * for the usb controller.
>> + */
>> +struct rockchip_xhci {
>> + struct usb_platdata usb_plat;
>> + struct xhci_ctrl ctrl;
>> + struct xhci_hccr *hcd;
>> + struct dwc3 *dwc3_reg;
>> + struct udevice *dev;
> What is dev used for? Can you please add a comment?
This dev is used for get the fdt from dev when do phy setup, but I think
this
can be removed.
>
>> +};
>> +
>> +static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
>> +{
>> + struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
>> + struct udevice *child;
>> + int ret = 0;
>> +
>> + /*
>> + * Get the base address for XHCI controller from the device node
>> + */
>> + plat->hcd_base = dev_get_addr(dev);
>> + if (plat->hcd_base == FDT_ADDR_T_NONE) {
>> + debug("Can't get the XHCI register base address\n");
>> + return -ENXIO;
>> + }
>> +
>> + /*
>> + * Get the base address for usbphy from the device node
>> + */
> /* Get the base address ... */
Will fix in next version.
>
>> + for (device_find_first_child(dev, &child); child;
>> + device_find_next_child(&child)) {
>> + if (!of_device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
>> + continue;
>> + plat->phy_base = dev_get_addr(child);
>> + break;
>> + }
>> +
>> + if (plat->phy_base == FDT_ADDR_T_NONE) {
>> + debug("Can't get the usbphy register address\n");
>> + return -ENXIO;
>> + }
>> +
>> + /* Vbus gpio */
>> + ret = gpio_request_by_name(dev, "rockchip,vbus-gpio", 0,
>> + &plat->vbus_gpio, GPIOD_IS_OUT);
>> + if (ret)
>> + debug("rockchip,vbus-gpio node missing!");
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * rockchip_dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
> * rockchip_dwc3_phy_setup() - Configure
Will fix in next version.
>
>> + * @dwc: Pointer to our controller context structure
>> + * @rockchip_xhci: Pointer to dev private data
>> + */
>> +static void rockchip_dwc3_phy_setup(struct dwc3 *dwc3_reg,
>> + struct rockchip_xhci *rockchip)
>> +{
>> + u32 reg;
>> + const void *blob = gd->fdt_blob;
>> + struct udevice *dev = rockchip->dev;
>> + const struct fdt_property *prop;
>> + const u32 *data;
>> +
>> + reg = readl(&dwc3_reg->g_usb3pipectl[0]);
>> +
>> + /* To do set dwc3 usb3 pipe control */
> Is this a TODO? If so:
>
> TODO(email): ...
Will remove in next version.
>
>> +
>> + writel(reg, &dwc3_reg->g_usb3pipectl[0]);
>> +
>> + /* Set dwc3 usb2 phy config */
> please drop this blank line
Will fix in next version.
>> +
>> + reg = readl(&dwc3_reg->g_usb2phycfg[0]);
>> +
>> + prop = fdt_get_property(blob, dev->of_offset,
>> + "snps,dis-enblslpm-quirk", NULL);
> Can you do:
>
> if (fdtdec_get_bool(blob, dev->of_offset, "snps,dis-enblslpm-quirk")
> reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
Will follow you suggestion in next version.
>
>> + if (prop)
>> + reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
>> +
>> + prop = fdt_get_property(blob, dev->of_offset,
>> + "snps,phyif-utmi-bits", NULL);
> I think you want fdtdec_get_int() here. It does the endianness
> conversion for you.
Will fix in next version.
>
>> + data = (u32 *)prop->data;
>> + if (fdt32_to_cpu(*data) == 16) {
>> + reg |= DWC3_GUSB2PHYCFG_PHYIF;
>> + reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
>> + reg |= 5 << DWC3_GUSB2PHYCFG_USBTRDTIM_OFFSET;
> What is 5 for? Please add a comment.
Will fix in next version.
>
>> + } else if (fdt32_to_cpu(*data) == 8) {
>> + reg &= ~DWC3_GUSB2PHYCFG_PHYIF;
>> + reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
>> + reg |= 9 << DWC3_GUSB2PHYCFG_USBTRDTIM_OFFSET;
> What is 9 for?
Will fix in next version.
>
>> + }
>> +
>> + prop = fdt_get_property(blob, dev->of_offset,
>> + "snps,dis-u2-freeclk-exists-quirk", NULL);
> fdtdec_get_bool
Will fix in next version.
>
>> + if (prop)
>> + reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
>> +
>> + prop = fdt_get_property(blob, dev->of_offset,
>> + "snps,dis-u2-susphy-quirk", NULL);
> fdtdec_get_bool
Will fix in next version.
>
>> + if (prop)
>> + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
>> +
>> + writel(reg, &dwc3_reg->g_usb2phycfg[0]);
>> +}
>> +
>> +static int rockchip_xhci_core_init(struct rockchip_xhci *rockchip)
>> +{
>> + int ret;
>> +
>> + ret = dwc3_core_init(rockchip->dwc3_reg);
>> + if (ret) {
>> + debug("failed to initialize core\n");
>> + return -EINVAL;
> return ret
Will fix in next version.
>
>> + }
>> +
>> + rockchip_dwc3_phy_setup(rockchip->dwc3_reg, rockchip);
>> +
>> + /* We are hard-coding DWC3 core to Host Mode */
>> + dwc3_set_mode(rockchip->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
>> +
>> + return 0;
>> +}
>> +
>> +static int rockchip_xhci_core_exit(struct rockchip_xhci *rockchip)
>> +{
>> + return 0;
>> +}
>> +
>> +static int xhci_usb_probe(struct udevice *dev)
>> +{
>> + struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
>> + struct rockchip_xhci *ctx = dev_get_priv(dev);
>> + struct xhci_hcor *hcor;
>> + int ret;
>> +
>> + ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
>> + ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
>> + ctx->dev = dev;
>> + hcor = (struct xhci_hcor *)((uint64_t)ctx->hcd +
>> + HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
>> +
>> + /* setup the Vbus gpio here */
>> + if (dm_gpio_is_valid(&plat->vbus_gpio))
>> + dm_gpio_set_value(&plat->vbus_gpio, 1);
>> +
>> + ret = rockchip_xhci_core_init(ctx);
>> + if (ret) {
>> + puts("XHCI: failed to initialize controller\n");
> debug()
Will fix in next version.
>
>> + return -EINVAL;
> return ret
Will fix in next version.
Thanks,
- Kever
>
>> + }
>> +
>> + return xhci_register(dev, ctx->hcd, hcor);
>> +}
>> +
>> +static int xhci_usb_remove(struct udevice *dev)
>> +{
>> + struct rockchip_xhci *ctx = dev_get_priv(dev);
>> + int ret;
>> +
>> + ret = xhci_deregister(dev);
>> + if (ret)
>> + return ret;
>> + ret = rockchip_xhci_core_exit(ctx);
>> + if (ret)
>> + return ret;
>> +
>> + return 0;
>> +}
>> +
>> +static const struct udevice_id xhci_usb_ids[] = {
>> + { .compatible = "rockchip,rk3399-xhci" },
>> + { }
>> +};
>> +
>> +U_BOOT_DRIVER(usb_xhci) = {
>> + .name = "xhci_rockchip",
>> + .id = UCLASS_USB,
>> + .of_match = xhci_usb_ids,
>> + .ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
>> + .probe = xhci_usb_probe,
>> + .remove = xhci_usb_remove,
>> + .ops = &xhci_usb_ops,
>> + .bind = dm_scan_fdt_dev,
>> + .platdata_auto_alloc_size = sizeof(struct rockchip_xhci_platdata),
>> + .priv_auto_alloc_size = sizeof(struct rockchip_xhci),
>> + .flags = DM_FLAG_ALLOC_PRIV_DMA,
>> +};
>> +
>> +static const struct udevice_id usb_phy_ids[] = {
>> + { .compatible = "rockchip,rk3399-usb3-phy" },
>> + { }
>> +};
>> +
>> +U_BOOT_DRIVER(usb_phy) = {
>> + .name = "usb_phy_rockchip",
>> + .of_match = usb_phy_ids,
>> +};
>> diff --git a/include/linux/usb/dwc3.h b/include/linux/usb/dwc3.h
>> index 6d1e365..b1e3d0a 100644
>> --- a/include/linux/usb/dwc3.h
>> +++ b/include/linux/usb/dwc3.h
>> @@ -180,7 +180,16 @@ struct dwc3 { /* offset: 0xC100 */
>>
>> /* Global USB2 PHY Configuration Register */
>> #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31)
>> +#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS (1 << 30)
>> +#define DWC3_GUSB2PHYCFG_ENBLSLPM (1 << 8)
>> #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6)
>> +#define DWC3_GUSB2PHYCFG_PHYIF (1 << 3)
>> +
>> +/* Global USB2 PHY Configuration Mask */
>> +#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASK (0xf << 10)
>> +
>> +/* Global USB2 PHY Configuration Offset */
>> +#define DWC3_GUSB2PHYCFG_USBTRDTIM_OFFSET 10
>>
>> /* Global USB3 PIPE Control Register */
>> #define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)
>> --
>> 1.9.1
>>
> Regards,
> Simon
>
>
>
next prev parent reply other threads:[~2016-08-24 3:34 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-19 7:19 [U-Boot] [PATCH v2 0/7] rk3399: enable host controllers Kever Yang
2016-08-19 7:19 ` [U-Boot] [PATCH v2 1/7] usb: xhci-rockchip: add rockchip dwc3 controller driver Kever Yang
2016-08-19 10:52 ` Marek Vasut
2016-08-24 3:06 ` Kever Yang
2016-08-22 4:20 ` Simon Glass
2016-08-24 3:34 ` Kever Yang [this message]
2016-08-19 7:19 ` [U-Boot] [PATCH v2 2/7] rockchip: select DM_USB for rockchip SoC Kever Yang
2016-08-19 7:19 ` [U-Boot] [PATCH v2 3/7] config: rk3399: add usb related configs Kever Yang
2016-08-19 7:19 ` [U-Boot] [PATCH v2 4/7] dts: rk3399: add dwc3_typec node for rk3399 Kever Yang
2016-08-19 7:19 ` [U-Boot] [PATCH v2 5/7] dts: rk3399-evb: add regulator-fixed for usb host vbus Kever Yang
2016-08-19 7:19 ` [U-Boot] [PATCH v2 6/7] board: evb-rk3399: enable usb 2.0 host vbus power on board_init Kever Yang
2016-08-22 4:20 ` Simon Glass
2016-08-19 7:19 ` [U-Boot] [PATCH v2 7/7] config: evb-rk3399: enable fixed regulator Kever Yang
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=57BD15D3.3030903@rock-chips.com \
--to=kever.yang@rock-chips.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.