From patchwork Tue Jul 18 07:56:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Lin X-Patchwork-Id: 9847167 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 00B63602C8 for ; Tue, 18 Jul 2017 07:58:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8CBD2621D for ; Tue, 18 Jul 2017 07:58:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DDC2627F54; Tue, 18 Jul 2017 07:58:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6943D2621D for ; Tue, 18 Jul 2017 07:58:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=QcRsVwVIgJsvuf+1YceGWNwSY8Ik0GO7zEI1fiRBf4E=; b=s9TfCFaSYTalEJjukp0m9kp8x1 tyDakTkSxWpmznLXyWrbmPrDyY80MnjYMhsmpcUgtkg7iLaYJT5voKjtAh2FpkZdF37MBafl1UfgM b/dEpY4XorBC08FHHTbUm/hF/sGVEC4LOxMQfyyNnAb92nuxT0xEfoVSQGAVfEbKUnJS+sl2NQT5t qGdQFm7EI2FTYUxHzt8z2p3lEwNc2hJDLown4vKSpIuCY0cmvF40B1Ui+LHxoP9TWmqwC/8G33bMC pwLXtCZY7AZoN4FkCJ4CY19BcTFOZpN9Fcjavarz56SXB6QTC4AURCRka4VQru89tFDzEZN0vxGdn Lbht/QWA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dXNP0-00055b-BI; Tue, 18 Jul 2017 07:58:42 +0000 Received: from lucky1.263xmail.com ([211.157.147.131]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dXNOf-0004VH-Ck for linux-rockchip@lists.infradead.org; Tue, 18 Jul 2017 07:58:24 +0000 Received: from shawn.lin?rock-chips.com (unknown [192.168.167.223]) by lucky1.263xmail.com (Postfix) with ESMTP id 941D98F859; Tue, 18 Jul 2017 15:57:59 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id 3E1F3378; Tue, 18 Jul 2017 15:57:56 +0800 (CST) X-RL-SENDER: shawn.lin@rock-chips.com X-FST-TO: bhelgaas@google.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: shawn.lin@rock-chips.com X-UNIQUE-TAG: <738f4861d1c8f191693f553c34588cd2> X-ATTACHMENT-NUM: 0 X-SENDER: lintao@rock-chips.com X-DNS-TYPE: 0 Received: from unknown (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith SMTP id 26973KYITTX; Tue, 18 Jul 2017 15:57:59 +0800 (CST) From: Shawn Lin To: Bjorn Helgaas , Kishon Vijay Abraham I Subject: [RFC PATCH v3 2/7] PCI: rockchip: introduce per-lanes PHYs support Date: Tue, 18 Jul 2017 15:56:58 +0800 Message-Id: <1500364623-97041-3-git-send-email-shawn.lin@rock-chips.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1500364623-97041-1-git-send-email-shawn.lin@rock-chips.com> References: <1500364623-97041-1-git-send-email-shawn.lin@rock-chips.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170718_005822_096419_71E5F6F3 X-CRM114-Status: GOOD ( 13.08 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Rob Herring , Brian Norris , Heiko Stuebner , devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Shawn Lin , Jeffy Chen , linux-rockchip@lists.infradead.org MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP We distinguish the legacy PHY with the newer per-lane PHYs by adding legacy_phy flag. Note that the legacy phy is still the first option to be searched in order not to break the backward compatibility of DTB. Signed-off-by: Shawn Lin Tested-by: Jeffy Chen --- Changes in v3: - kill rockchip_pcie_manipulate_phys and related stuff - use phys array - improve the commit msg Changes in v2: None drivers/pci/host/pcie-rockchip.c | 100 +++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index 6632a51..4cc6aec 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c @@ -47,6 +47,7 @@ #define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) #define ENCODE_LANES(x) ((((x) >> 1) & 3) << 4) +#define MAX_LANE_NUM 4 #define PCIE_CLIENT_BASE 0x0 #define PCIE_CLIENT_CONFIG (PCIE_CLIENT_BASE + 0x00) @@ -210,7 +211,8 @@ struct rockchip_pcie { void __iomem *reg_base; /* DT axi-base */ void __iomem *apb_base; /* DT apb-base */ - struct phy *phy; + bool legacy_phy; + struct phy *phys[MAX_LANE_NUM]; struct reset_control *core_rst; struct reset_control *mgmt_rst; struct reset_control *mgmt_sticky_rst; @@ -507,6 +509,46 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip) rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR); } +static int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip) +{ + struct device *dev = rockchip->dev; + struct phy *phy; + char *name; + u32 i; + + rockchip->phys[0] = devm_phy_get(dev, "pcie-phy"); + if (IS_ERR(rockchip->phys[0])) { + if (PTR_ERR(rockchip->phys[0]) == -EPROBE_DEFER) + return PTR_ERR(rockchip->phys[0]); + dev_dbg(dev, "missing legacy phy, and search for per-lane PHY\n"); + } else { + rockchip->legacy_phy = true; + dev_warn(dev, "legacy phy model is deprecated!\n"); + return 0; + } + + for (i = 0; i < MAX_LANE_NUM; i++) { + name = kasprintf(GFP_KERNEL, "pcie-phy-%u", i); + if (!name) + return -ENOMEM; + + phy = devm_of_phy_get(rockchip->dev, + rockchip->dev->of_node, name); + kfree(name); + + if (IS_ERR(phy)) { + if (PTR_ERR(phy) != -EPROBE_DEFER) + dev_err(dev, "missing phy for lane %d: %ld\n", + i, PTR_ERR(phy)); + return PTR_ERR(phy); + } + + rockchip->phys[i] = phy; + } + + return 0; +} + /** * rockchip_pcie_init_port - Initialize hardware * @rockchip: PCIe port information @@ -514,7 +556,7 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip) static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) { struct device *dev = rockchip->dev; - int err; + int err, i; u32 status; gpiod_set_value(rockchip->ep_gpio, 0); @@ -537,10 +579,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) return err; } - err = phy_init(rockchip->phy); - if (err < 0) { - dev_err(dev, "fail to init phy, err %d\n", err); - return err; + for (i = 0; i < MAX_LANE_NUM; i++) { + err = phy_init(rockchip->phys[i]); + if (err) { + dev_err(dev, "init phy err %d\n", err); + return err; + } } err = reset_control_assert(rockchip->core_rst); @@ -602,10 +646,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) PCIE_CLIENT_MODE_RC, PCIE_CLIENT_CONFIG); - err = phy_power_on(rockchip->phy); - if (err) { - dev_err(dev, "fail to power on phy, err %d\n", err); - return err; + for (i = 0; i < MAX_LANE_NUM; i++) { + err = phy_power_on(rockchip->phys[i]); + if (err) { + dev_err(dev, "power on phy err %d\n", err); + return err; + } } /* @@ -853,20 +899,6 @@ static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } -static int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip) -{ - struct device *dev = rockchip->dev; - - rockchip->phy = devm_phy_get(dev, "pcie-phy"); - if (IS_ERR(rockchip->phy)) { - if (PTR_ERR(rockchip->phy) != -EPROBE_DEFER) - dev_err(dev, "missing phy\n"); - return PTR_ERR(rockchip->phy); - } - - return 0; -} - /** * rockchip_pcie_parse_dt - Parse Device Tree * @rockchip: PCIe port information @@ -896,8 +928,9 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) if (IS_ERR(rockchip->apb_base)) return PTR_ERR(rockchip->apb_base); - if (rockchip_pcie_get_phys(rockchip)) - return PTR_ERR(rockchip->phy); + err = rockchip_pcie_get_phys(rockchip); + if (err) + return err; rockchip->lanes = 1; err = of_property_read_u32(node, "num-lanes", &rockchip->lanes); @@ -1282,7 +1315,7 @@ static int rockchip_pcie_wait_l2(struct rockchip_pcie *rockchip) static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev) { struct rockchip_pcie *rockchip = dev_get_drvdata(dev); - int ret; + int ret, i; /* disable core and cli int since we don't need to ack PME_ACK */ rockchip_pcie_write(rockchip, (PCIE_CLIENT_INT_CLI << 16) | @@ -1295,8 +1328,10 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev) return ret; } - phy_power_off(rockchip->phy); - phy_exit(rockchip->phy); + for (i = 0; i < MAX_LANE_NUM; i++) { + phy_power_off(rockchip->phys[i]); + phy_exit(rockchip->phys[i]); + } clk_disable_unprepare(rockchip->clk_pcie_pm); clk_disable_unprepare(rockchip->hclk_pcie); @@ -1532,14 +1567,17 @@ static int rockchip_pcie_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rockchip_pcie *rockchip = dev_get_drvdata(dev); + int i; pci_stop_root_bus(rockchip->root_bus); pci_remove_root_bus(rockchip->root_bus); pci_unmap_iospace(rockchip->io); irq_domain_remove(rockchip->irq_domain); - phy_power_off(rockchip->phy); - phy_exit(rockchip->phy); + for (i = 0; i < MAX_LANE_NUM; i++) { + phy_power_off(rockchip->phys[i]); + phy_exit(rockchip->phys[i]); + } clk_disable_unprepare(rockchip->clk_pcie_pm); clk_disable_unprepare(rockchip->hclk_pcie);