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:
William Wu
2018-07-19 16:01:57 +08:00
committed by Tao Huang
parent a03c5f1ef5
commit 4e5b4527dd
3 changed files with 27 additions and 0 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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)