mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 21:24:00 +08:00
- Adding ULPI PHY support for imx53
- Properly mark little endian descriptors for udc -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJYO4X5AAoJEEhZKYFQ1nG78yYH/A8GJ6a3pBwvgF3XUhZusp75 w1yg7TnP4aPXDFdS2dpS0buFrBji/0MxTZm3aKNKIHL2jF6ZRW5TvhapA9xv7ezY BhJOMXMUQAQSG/hnnu8QBJcrd0de3+EUhK6jYKInhvtNQUWl1jW073VAudlp2u4L lVeHg49+u/10KlZ1Y6yipOH/KzfrOM1oGYBwyl7KMA48R2EASJ0FATcwUM/tRUX3 n6suCg/Z0VVFRdeYkiJdgnjxIbI+QR6TPMV+MWT1O32EniWm3pQT4G3WODooVqO9 oLc+4xgMoPkoiN5XwkYRNZ3wqhDp7xk2v10XJ7zTP1Xrqt2YFBk8K+Ls2/eQmGU= =uOYb -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
9dd649c639
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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,31 +211,77 @@ 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:
|
||||
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;
|
||||
break;
|
||||
case 1:
|
||||
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;
|
||||
break;
|
||||
case 2:
|
||||
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;
|
||||
break;
|
||||
case 3:
|
||||
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;
|
||||
break;
|
||||
}
|
||||
if (reg && val)
|
||||
writel(val, reg);
|
||||
spin_unlock_irqrestore(&usbmisc->lock, flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&usbmisc->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user