Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9dd649c6 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'usb-ci-v4.10-rc1' of...

Merge tag 'usb-ci-v4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb into usb-next

Peter writes:

- Adding ULPI PHY support for imx53
- Properly mark little endian descriptors for udc
parents 75e9ebec 3be3251d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/pm_runtime.h>
#include <linux/dma-mapping.h>
#include <linux/usb/chipidea.h>
#include <linux/usb/of.h>
#include <linux/clk.h>

#include "ci.h"
@@ -146,6 +147,9 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
	if (of_find_property(np, "external-vbus-divider", NULL))
		data->evdo = 1;

	if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
		data->ulpi = 1;

	return data;
}

+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ struct imx_usbmisc_data {
	unsigned int disable_oc:1; /* over current detect disabled */
	unsigned int oc_polarity:1; /* over current polarity if oc enabled */
	unsigned int evdo:1; /* set external vbus divider option */
	unsigned int ulpi:1; /* connected to an ULPI phy */
};

int imx_usbmisc_init(struct imx_usbmisc_data *);
+3 −3
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq,
		if (hwreq->req.length == 0
				|| hwreq->req.length % hwep->ep.maxpacket)
			mul++;
		node->ptr->token |= mul << __ffs(TD_MULTO);
		node->ptr->token |= cpu_to_le32(mul << __ffs(TD_MULTO));
	}

	temp = (u32) (hwreq->req.dma + hwreq->req.actual);
@@ -504,7 +504,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
		if (hwreq->req.length == 0
				|| hwreq->req.length % hwep->ep.maxpacket)
			mul++;
		hwep->qh.ptr->cap |= mul << __ffs(QH_MULT);
		hwep->qh.ptr->cap |= cpu_to_le32(mul << __ffs(QH_MULT));
	}

	ret = hw_ep_prime(ci, hwep->num, hwep->dir,
@@ -529,7 +529,7 @@ static void free_pending_td(struct ci_hw_ep *hwep)
static int reprime_dtd(struct ci_hdrc *ci, struct ci_hw_ep *hwep,
					   struct td_node *node)
{
	hwep->qh.ptr->td.next = node->dma;
	hwep->qh.ptr->td.next = cpu_to_le32(node->dma);
	hwep->qh.ptr->td.token &=
		cpu_to_le32(~(TD_STATUS_HALTED | TD_STATUS_ACTIVE));

+6 −6
Original line number Diff line number Diff line
@@ -22,11 +22,11 @@
/* DMA layout of transfer descriptors */
struct ci_hw_td {
	/* 0 */
	u32 next;
	__le32 next;
#define TD_TERMINATE          BIT(0)
#define TD_ADDR_MASK          (0xFFFFFFEUL << 5)
	/* 1 */
	u32 token;
	__le32 token;
#define TD_STATUS             (0x00FFUL <<  0)
#define TD_STATUS_TR_ERR      BIT(3)
#define TD_STATUS_DT_ERR      BIT(5)
@@ -36,7 +36,7 @@ struct ci_hw_td {
#define TD_IOC                BIT(15)
#define TD_TOTAL_BYTES        (0x7FFFUL << 16)
	/* 2 */
	u32 page[5];
	__le32 page[5];
#define TD_CURR_OFFSET        (0x0FFFUL <<  0)
#define TD_FRAME_NUM          (0x07FFUL <<  0)
#define TD_RESERVED_MASK      (0x0FFFUL <<  0)
@@ -45,18 +45,18 @@ struct ci_hw_td {
/* DMA layout of queue heads */
struct ci_hw_qh {
	/* 0 */
	u32 cap;
	__le32 cap;
#define QH_IOS                BIT(15)
#define QH_MAX_PKT            (0x07FFUL << 16)
#define QH_ZLT                BIT(29)
#define QH_MULT               (0x0003UL << 30)
#define QH_ISO_MULT(x)		((x >> 11) & 0x03)
	/* 1 */
	u32 curr;
	__le32 curr;
	/* 2 - 8 */
	struct ci_hw_td		td;
	/* 9 */
	u32 RESERVED;
	__le32 RESERVED;
	struct usb_ctrlrequest   setup;
} __attribute__ ((packed, aligned(4)));

+72 −14
Original line number Diff line number Diff line
@@ -46,11 +46,23 @@

#define MX53_USB_OTG_PHY_CTRL_0_OFFSET	0x08
#define MX53_USB_OTG_PHY_CTRL_1_OFFSET	0x0c
#define MX53_USB_CTRL_1_OFFSET	        0x10
#define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2)
#define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2)
#define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6)
#define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6)
#define MX53_USB_UH2_CTRL_OFFSET	0x14
#define MX53_USB_UH3_CTRL_OFFSET	0x18
#define MX53_USB_CLKONOFF_CTRL_OFFSET	0x24
#define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21)
#define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22)
#define MX53_BM_OVER_CUR_DIS_H1		BIT(5)
#define MX53_BM_OVER_CUR_DIS_OTG	BIT(8)
#define MX53_BM_OVER_CUR_DIS_UHx	BIT(30)
#define MX53_USB_CTRL_1_UH2_ULPI_EN	BIT(26)
#define MX53_USB_CTRL_1_UH3_ULPI_EN	BIT(27)
#define MX53_USB_UHx_CTRL_WAKE_UP_EN	BIT(7)
#define MX53_USB_UHx_CTRL_ULPI_INT_EN	BIT(8)
#define MX53_USB_PHYCTRL1_PLLDIV_MASK	0x3
#define MX53_USB_PLL_DIV_24_MHZ		0x01

@@ -199,30 +211,76 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
	val |= MX53_USB_PLL_DIV_24_MHZ;
	writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET);

	if (data->disable_oc) {
	spin_lock_irqsave(&usbmisc->lock, flags);

	switch (data->index) {
	case 0:
		if (data->disable_oc) {
			reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
			val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG;
			writel(val, reg);
		}
		break;
	case 1:
		if (data->disable_oc) {
			reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET;
			val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1;
			writel(val, reg);
		}
		break;
	case 2:
		if (data->ulpi) {
			/* set USBH2 into ULPI-mode. */
			reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET;
			val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN;
			/* select ULPI clock */
			val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK;
			val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI;
			writel(val, reg);
			/* Set interrupt wake up enable */
			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN
				| MX53_USB_UHx_CTRL_ULPI_INT_EN;
			writel(val, reg);
			/* Disable internal 60Mhz clock */
			reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET;
			val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF;
			writel(val, reg);
		}
		if (data->disable_oc) {
			reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET;
			val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
			writel(val, reg);
		}
		break;
	case 3:
		if (data->ulpi) {
			/* set USBH3 into ULPI-mode. */
			reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET;
			val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN;
			/* select ULPI clock */
			val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK;
			val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI;
			writel(val, reg);
			/* Set interrupt wake up enable */
			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
			val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN
				| MX53_USB_UHx_CTRL_ULPI_INT_EN;
			writel(val, reg);
			/* Disable internal 60Mhz clock */
			reg = usbmisc->base + MX53_USB_CLKONOFF_CTRL_OFFSET;
			val = readl(reg) | MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF;
			writel(val, reg);
		}
		if (data->disable_oc) {
			reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET;
			val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx;
			writel(val, reg);
		}
		break;
	}
		if (reg && val)
			writel(val, reg);

	spin_unlock_irqrestore(&usbmisc->lock, flags);
	}

	return 0;
}