Re: [PATCH 1/2] usb: chipidea: imx: add usb support for imx7d

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Sep 09, 2015 at 10:18:39AM +0800, Li Jun wrote:
> Add imx7d usb support.
> 
> Signed-off-by: Li Jun <jun.li@xxxxxxxxxxxxx>
> ---
>  drivers/usb/chipidea/ci_hdrc_imx.c |    7 ++++
>  drivers/usb/chipidea/usbmisc_imx.c |   62 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+)
> 
> diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
> index 867e9f3..f9deea5 100644
> --- a/drivers/usb/chipidea/ci_hdrc_imx.c
> +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
> @@ -56,12 +56,19 @@ static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
>  		CI_HDRC_DISABLE_HOST_STREAMING,
>  };
>  
> +static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
> +	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
> +		CI_HDRC_TURN_VBUS_EARLY_ON |
> +		CI_HDRC_DISABLE_HOST_STREAMING,
> +};
> +

For imx7, it uses v2.5 core, we don't need to disable stream mode
for host.

The reason for i.mx to disable host stream mode is below issue
(see 8022d3d51c6fb14736e26fd13caca91a38e07580)

TAR 9000378958
    Title: Non-Double Word Aligned Buffer Address Sometimes Causes Host
    to Hang on OUT Retry

At v2.5 core, this bug has fixed by IP vendor.

>  static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
>  	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
>  	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
>  	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
>  	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
>  	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sl_usb_data},
> +	{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
> diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
> index 5ddab30..f3a4753 100644
> --- a/drivers/usb/chipidea/usbmisc_imx.c
> +++ b/drivers/usb/chipidea/usbmisc_imx.c
> @@ -72,6 +72,14 @@
>  
>  #define VF610_OVER_CUR_DIS		BIT(7)
>  
> +#define MX7D_USBNC_USB_CTRL2		0x4
> +#define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK	0x3
> +#define MX7D_USB_VBUS_WAKEUP_SOURCE(v)		(v << 0)
> +#define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS	MX7D_USB_VBUS_WAKEUP_SOURCE(0)
> +#define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(1)
> +#define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(2)
> +#define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX7D_USB_VBUS_WAKEUP_SOURCE(3)
> +
>  struct usbmisc_ops {
>  	/* It's called once when probe a usb device */
>  	int (*init)(struct imx_usbmisc_data *data);
> @@ -324,6 +332,55 @@ static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
>  	return 0;
>  }
>  
> +static int usbmisc_imx7d_set_wakeup
> +	(struct imx_usbmisc_data *data, bool enabled)
> +{
> +	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
> +	unsigned long flags;
> +	u32 val;
> +	u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE |
> +		MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP);
> +
> +	spin_lock_irqsave(&usbmisc->lock, flags);
> +	val = readl(usbmisc->base);
> +	if (enabled) {
> +		writel(val | wakeup_setting, usbmisc->base);
> +	} else {
> +		if (val & MX6_BM_WAKEUP_INTR)
> +			dev_dbg(data->dev, "wakeup int\n");
> +		writel(val & ~wakeup_setting, usbmisc->base);
> +	}
> +	spin_unlock_irqrestore(&usbmisc->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
> +{
> +	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
> +	unsigned long flags;
> +	u32 reg;
> +
> +	if (data->index >= 1)
> +		return -EINVAL;
> +
> +	spin_lock_irqsave(&usbmisc->lock, flags);
> +	if (data->disable_oc) {
> +		reg = readl(usbmisc->base);
> +		writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base);
> +	}
> +
> +	reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
> +	reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
> +	writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
> +		 usbmisc->base + MX7D_USBNC_USB_CTRL2);
> +	spin_unlock_irqrestore(&usbmisc->lock, flags);
> +
> +	usbmisc_imx7d_set_wakeup(data, false);
> +
> +	return 0;
> +}
> +
>  static const struct usbmisc_ops imx25_usbmisc_ops = {
>  	.init = usbmisc_imx25_init,
>  	.post = usbmisc_imx25_post,
> @@ -351,6 +408,11 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = {
>  	.init = usbmisc_imx6sx_init,
>  };
>  
> +static const struct usbmisc_ops imx7d_usbmisc_ops = {
> +	.init = usbmisc_imx7d_init,
> +	.set_wakeup = usbmisc_imx7d_set_wakeup,
> +};
> +
>  int imx_usbmisc_init(struct imx_usbmisc_data *data)
>  {
>  	struct imx_usbmisc *usbmisc;
> -- 
> 1.7.9.5
> 

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux