From patchwork Mon Apr 10 13:17:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 97160 Delivered-To: patch@linaro.org Received: by 10.182.246.10 with SMTP id xs10csp1354378obc; Mon, 10 Apr 2017 06:24:44 -0700 (PDT) X-Received: by 10.84.224.206 with SMTP id k14mr9814841pln.159.1491830684173; Mon, 10 Apr 2017 06:24:44 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h9si13634287pli.267.2017.04.10.06.24.43; Mon, 10 Apr 2017 06:24:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753947AbdDJNYf (ORCPT + 24 others); Mon, 10 Apr 2017 09:24:35 -0400 Received: from lelnx194.ext.ti.com ([198.47.27.80]:57538 "EHLO lelnx194.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753784AbdDJNS6 (ORCPT ); Mon, 10 Apr 2017 09:18:58 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelnx194.ext.ti.com (8.15.1/8.15.1) with ESMTP id v3ADIb8t000898; Mon, 10 Apr 2017 08:18:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com; s=ti-com-17Q1; t=1491830317; bh=TdEuSNJhMMQQtWvhCynC+nI5RcvPxtbA12vgPNQnBf4=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Y8AuHiLJ1rbe745uxHqZ4EGyjLuCQGOtErVbu9ttA1LlwiZjBslkgiZlk6/jFHkey n8FLBIcOw2MBlHJ3NGnkL19VQVPfLWPvzeSLBQ9FyBLiBDlNNDxXMSCZnjsC/GJIXT RhXu4pZj0N1/Cb9JRkgXzIY1OoextOSNQF372T1Y= Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id v3ADIbKH027263; Mon, 10 Apr 2017 08:18:37 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.294.0; Mon, 10 Apr 2017 08:18:36 -0500 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id v3ADIOM1032573; Mon, 10 Apr 2017 08:18:35 -0500 From: Kishon Vijay Abraham I To: CC: , Subject: [PATCH 07/32] phy: sun4i-usb: support automatically switch PHY0 route to MUSB/HCI Date: Mon, 10 Apr 2017 18:47:58 +0530 Message-ID: <20170410131823.26485-8-kishon@ti.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170410131823.26485-1-kishon@ti.com> References: <20170410131823.26485-1-kishon@ti.com> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Icenowy Zheng On newer Allwinner SoCs (H3 and after), the PHY0 node is routed to both MUSB controller for peripheral and host support (the host support is slightly broken), and a pair of EHCI/OHCI controllers, which provide a better support for host mode. Add support for automatically switch the route of PHY0 according to the status of dr_mode and id det pin. Only H3 have this function enabled in this patch, as further SoCs will be tested later and then have it enabled. As H5 is reusing the PHY driver of H3, this function is also enabled. Signed-off-by: Icenowy Zheng Acked-by: Chen-Yu Tsai Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-sun4i-usb.c | 50 ++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 17 deletions(-) -- 2.11.0 diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index a650f283f6ff..f86a2574b953 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -49,12 +49,14 @@ #define REG_PHYBIST 0x08 #define REG_PHYTUNE 0x0c #define REG_PHYCTL_A33 0x10 -#define REG_PHY_UNK_H3 0x20 +#define REG_PHY_OTGCTL 0x20 #define REG_PMU_UNK1 0x10 #define PHYCTL_DATA BIT(7) +#define OTGCTL_ROUTE_MUSB BIT(0) + #define SUNXI_AHB_ICHR8_EN BIT(10) #define SUNXI_AHB_INCR4_BURST_EN BIT(9) #define SUNXI_AHB_INCRX_ALIGN_EN BIT(8) @@ -110,6 +112,7 @@ struct sun4i_usb_phy_cfg { u8 phyctl_offset; bool dedicated_clocks; bool enable_pmu_unk1; + bool phy0_dual_route; }; struct sun4i_usb_phy_data { @@ -269,23 +272,16 @@ static int sun4i_usb_phy_init(struct phy *_phy) writel(val & ~2, phy->pmu + REG_PMU_UNK1); } - if (data->cfg->type == sun8i_h3_phy) { - if (phy->index == 0) { - val = readl(data->base + REG_PHY_UNK_H3); - writel(val & ~1, data->base + REG_PHY_UNK_H3); - } - } else { - /* Enable USB 45 Ohm resistor calibration */ - if (phy->index == 0) - sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); + /* Enable USB 45 Ohm resistor calibration */ + if (phy->index == 0) + sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); - /* Adjust PHY's magnitude and rate */ - sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); + /* Adjust PHY's magnitude and rate */ + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); - /* Disconnect threshold adjustment */ - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, - data->cfg->disc_thresh, 2); - } + /* Disconnect threshold adjustment */ + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, + data->cfg->disc_thresh, 2); sun4i_usb_phy_passby(phy, 1); @@ -484,6 +480,21 @@ static const struct phy_ops sun4i_usb_phy_ops = { .owner = THIS_MODULE, }; +static void sun4i_usb_phy0_reroute(struct sun4i_usb_phy_data *data, int id_det) +{ + u32 regval; + + regval = readl(data->base + REG_PHY_OTGCTL); + if (id_det == 0) { + /* Host mode. Route phy0 to EHCI/OHCI */ + regval &= ~OTGCTL_ROUTE_MUSB; + } else { + /* Peripheral mode. Route phy0 to MUSB */ + regval |= OTGCTL_ROUTE_MUSB; + } + writel(regval, data->base + REG_PHY_OTGCTL); +} + static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) { struct sun4i_usb_phy_data *data = @@ -544,6 +555,10 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) sun4i_usb_phy0_set_vbus_detect(phy0, 1); mutex_unlock(&phy0->mutex); } + + /* Re-route PHY0 if necessary */ + if (data->cfg->phy0_dual_route) + sun4i_usb_phy0_reroute(data, id_det); } if (vbus_notify) @@ -698,7 +713,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(phy->reset); } - if (i) { /* No pmu for usbc0 */ + if (i || data->cfg->phy0_dual_route) { /* No pmu for musb */ snprintf(name, sizeof(name), "pmu%d", i); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); @@ -824,6 +839,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { .phyctl_offset = REG_PHYCTL_A33, .dedicated_clocks = true, .enable_pmu_unk1 = true, + .phy0_dual_route = true, }; static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {