From patchwork Tue May 6 13:33:50 2014 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: 4121481 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 553EB9F1E1 for ; Tue, 6 May 2014 13:37:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5912E2020F for ; Tue, 6 May 2014 13:37:57 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 59DCA201ED for ; Tue, 6 May 2014 13:37:56 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WhfWc-00040q-KB; Tue, 06 May 2014 13:35:14 +0000 Received: from devils.ext.ti.com ([198.47.26.153]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WhfWP-0002l8-5o for linux-arm-kernel@lists.infradead.org; Tue, 06 May 2014 13:35:02 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id s46DYilZ005243; Tue, 6 May 2014 08:34:44 -0500 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 s46DYiGA031830; Tue, 6 May 2014 08:34:44 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Tue, 6 May 2014 08:34:43 -0500 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s46DYE8T031249; Tue, 6 May 2014 08:34:41 -0500 From: Kishon Vijay Abraham I To: , , , , , Subject: [PATCH 04/17] phy: pipe3: insert delay to enumerate in GEN2 mode Date: Tue, 6 May 2014 19:03:50 +0530 Message-ID: <1399383244-14556-5-git-send-email-kishon@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1399383244-14556-1-git-send-email-kishon@ti.com> References: <1399383244-14556-1-git-send-email-kishon@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140506_063501_658343_B6F37DCF X-CRM114-Status: GOOD ( 15.17 ) X-Spam-Score: -5.7 (-----) Cc: Kishon Vijay Abraham I , balajitk@ti.com, rogerq@ti.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 8-bit delay value (0xF1) is required for GEN2 devices to be enumerated consistently. Added an API to be called from PHY drivers to set this delay value and called it from PIPE3 driver to set the delay value. Signed-off-by: Kishon Vijay Abraham I Reviewed-by: Roger Quadros --- Documentation/devicetree/bindings/phy/ti-phy.txt | 4 +-- drivers/phy/phy-omap-control.c | 41 ++++++++++++++++++++++ drivers/phy/phy-ti-pipe3.c | 4 ++- include/linux/phy/omap_control_phy.h | 9 +++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index d50f8ee..5653dc4 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt @@ -18,9 +18,9 @@ Required properties: AM437 platform. - reg : Address and length of the register set for the device. It contains the address of "otghs_control" for control-phy-otghs or "power" register - for other types and "control_sma" for control-phy-pcie + for other types and "control_sma", "pcie_pcs" for control-phy-pcie - reg-names: should be "otghs_control" for control-phy-otghs, - "control_sma" for control-phy-pcie and "power" for other types. + "control_sma", "pcie_pcs" for control-phy-pcie and "power" for other types. omap_control_usb: omap-control-usb@4a002300 { compatible = "ti,control-phy-otghs"; diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index 47a1b6c..6ba551b 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c @@ -61,6 +61,41 @@ void omap_control_pcie_tx_rx_control(struct device *dev, u8 ctrl) EXPORT_SYMBOL_GPL(omap_control_pcie_tx_rx_control); /** + * omap_control_pcie_pcs - set the PCS delay count + * @dev: the control module device + * @id: index of the pcie PHY (should be 1 or 2) + * @delay: 8 bit delay value + */ +void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +{ + u32 val; + struct omap_control_phy *control_phy; + + if (IS_ERR(dev) || !dev) { + pr_err("%s: invalid device\n", __func__); + return; + } + + control_phy = dev_get_drvdata(dev); + if (!control_phy) { + dev_err(dev, "%s: invalid control phy device\n", __func__); + return; + } + + if (control_phy->type != OMAP_CTRL_TYPE_PCIE) { + dev_err(dev, "%s: unsupported operation\n", __func__); + return; + } + + val = readl(control_phy->pcie_pcs); + val &= ~(OMAP_CTRL_PCIE_PCS_MASK << + (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); + val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + writel(val, control_phy->pcie_pcs); +} +EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); + +/** * omap_control_phy_power - power on/off the phy using control module reg * @dev: the control module device * @on: 0 or 1, based on powering on or off the PHY @@ -335,6 +370,12 @@ static int omap_control_phy_probe(struct platform_device *pdev) control_phy->ctrl_sma = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(control_phy->ctrl_sma)) return PTR_ERR(control_phy->ctrl_sma); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pcie_pcs"); + control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(control_phy->pcie_pcs)) + return PTR_ERR(control_phy->pcie_pcs); } dev_set_drvdata(control_phy->dev, control_phy); diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 5513aa0..a1a0e35 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -216,8 +216,10 @@ static int ti_pipe3_init(struct phy *x) u32 val; int ret = 0; - if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) + if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { + omap_control_pcie_pcs(phy->control_dev, 0x1, 0xF1); return 0; + } /* Bring it out of IDLE if it is IDLE */ val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); diff --git a/include/linux/phy/omap_control_phy.h b/include/linux/phy/omap_control_phy.h index 15cfbfe..6127c04 100644 --- a/include/linux/phy/omap_control_phy.h +++ b/include/linux/phy/omap_control_phy.h @@ -35,6 +35,7 @@ struct omap_control_phy { u32 __iomem *power; u32 __iomem *power_aux; u32 __iomem *ctrl_sma; + u32 __iomem *pcie_pcs; struct clk *sys_clk; @@ -68,6 +69,9 @@ enum omap_control_usb_mode { #define OMAP_CTRL_PCIE_TX_RX_CONTROL_SHIFT 0x10 #define OMAP_CTRL_PCIE_TX_RX_CONTROL_MASK 0x3 +#define OMAP_CTRL_PCIE_PCS_MASK 0xff +#define OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT 0x8 + #define OMAP_CTRL_PCIE_PHY_TX_ACSPCIE 0x1 #define OMAP_CTRL_PCIE_PHY_RX_ACSPCIE 0x2 #define OMAP_CTRL_PCIE_PHY_TX_RX_ACSPCIE 0x3 @@ -84,6 +88,7 @@ void omap_control_phy_power(struct device *dev, int on); void omap_control_usb_set_mode(struct device *dev, enum omap_control_usb_mode mode); void omap_control_pcie_tx_rx_control(struct device *dev, u8 ctrl); +void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay); #else static inline void omap_control_phy_power(struct device *dev, int on) @@ -98,6 +103,10 @@ static inline void omap_control_usb_set_mode(struct device *dev, static inline void omap_control_pcie_tx_rx_control(struct device *dev, u8 ctrl) { } + +static inline void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +{ +} #endif #endif /* __OMAP_CONTROL_PHY_H__ */