mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
USB: ehci-platform: support EHCIs with usic phy
Some EHCI controllers use usic phy (e.g rk3399/rk3288),
in order to enable these controllers, we need to set
some additional EHCI vendor-specific registers.
Support this feature in device tree when using the ehci
platform driver by adding a new property for it.
Conflicts:
drivers/usb/host/ehci-platform.c
Change-Id: I279ccfdb5866df49828825bfd41b39fcd58a2832
Signed-off-by: William Wu <william.wu@rock-chips.com>
Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
This commit is contained in:
@@ -15,6 +15,7 @@ Optional properties:
|
||||
- needs-reset-on-resume : boolean, set this to force EHCI reset after resume
|
||||
- has-transaction-translator : boolean, set this if EHCI have a Transaction
|
||||
Translator built into the root hub.
|
||||
- rockchip-has-usic : boolean, set this if EHCI use usic phy.
|
||||
- clocks : a list of phandle + clock specifier pairs
|
||||
- phys : see usb-hcd.txt in the current directory
|
||||
- resets : phandle + reset specifier pair
|
||||
|
||||
@@ -60,6 +60,18 @@ static void ehci_rockchip_relinquish_port(struct usb_hcd *hcd, int portnum)
|
||||
ehci_writel(ehci, portsc, status_reg);
|
||||
}
|
||||
|
||||
static void ehci_rockchip_usic_init(struct usb_hcd *hcd)
|
||||
{
|
||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||
|
||||
ehci_writel(ehci, USIC_ENABLE,
|
||||
hcd->regs + USIC_ENABLE_OFFSET);
|
||||
ehci_writel(ehci, USIC_MICROFRAME_COUNT,
|
||||
hcd->regs + USIC_MICROFRAME_OFFSET);
|
||||
ehci_writel(ehci, USIC_SCALE_DOWN,
|
||||
hcd->regs + USIC_SCALE_DOWN_OFFSET);
|
||||
}
|
||||
|
||||
static int ehci_platform_reset(struct usb_hcd *hcd)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(hcd->self.controller);
|
||||
@@ -198,6 +210,10 @@ static int ehci_platform_probe(struct platform_device *dev)
|
||||
hcd->rk3288_relinquish_port_quirk = 1;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(dev->dev.of_node,
|
||||
"rockchip-has-usic"))
|
||||
ehci->has_usic = 1;
|
||||
|
||||
for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
|
||||
priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
|
||||
if (IS_ERR(priv->clks[clk])) {
|
||||
@@ -265,6 +281,9 @@ static int ehci_platform_probe(struct platform_device *dev)
|
||||
if (err)
|
||||
goto err_power;
|
||||
|
||||
if (ehci->has_usic)
|
||||
ehci_rockchip_usic_init(hcd);
|
||||
|
||||
device_wakeup_enable(hcd->self.controller);
|
||||
device_enable_async_suspend(hcd->self.controller);
|
||||
platform_set_drvdata(dev, hcd);
|
||||
|
||||
@@ -218,6 +218,13 @@ struct ehci_hcd { /* one per controller */
|
||||
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
|
||||
unsigned need_oc_pp_cycle:1; /* MPC834X port power */
|
||||
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
|
||||
unsigned has_usic:1;
|
||||
#define USIC_MICROFRAME_OFFSET 0x90
|
||||
#define USIC_SCALE_DOWN_OFFSET 0xa0
|
||||
#define USIC_ENABLE_OFFSET 0xb0
|
||||
#define USIC_ENABLE BIT(0)
|
||||
#define USIC_SCALE_DOWN BIT(2)
|
||||
#define USIC_MICROFRAME_COUNT 0x1d4d
|
||||
|
||||
/* required for usb32 quirk */
|
||||
#define OHCI_CTRL_HCFS (3 << 6)
|
||||
|
||||
Reference in New Issue
Block a user