From patchwork Wed Apr 20 15:45:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Smirnov X-Patchwork-Id: 8892581 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1D58FBF29F for ; Wed, 20 Apr 2016 15:47:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EF22D20145 for ; Wed, 20 Apr 2016 15:47:45 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DA37B200FF for ; Wed, 20 Apr 2016 15:47:44 +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 1asuKW-000344-W4; Wed, 20 Apr 2016 15:46:17 +0000 Received: from mail-io0-x235.google.com ([2607:f8b0:4001:c06::235]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1asuKQ-0002sH-Sj for linux-arm-kernel@lists.infradead.org; Wed, 20 Apr 2016 15:46:12 +0000 Received: by mail-io0-x235.google.com with SMTP id u185so56452140iod.3 for ; Wed, 20 Apr 2016 08:45:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=VchOYy/xvIndvfhwFWjIHrrlLTEcDzjOlW3vYyHU+LA=; b=dslmYdWeRJ9QogZrI6zmDooVMnrguc/JI0neRUt8bWTlvafnSah2vNj08OPovRoYyW ZKtPYa8+1n584Q0jSgRydRihxTmh/YhHPEtIeh4QZ6uGA2OrkU+LzXZ7MzMHjQwqCbYq N4qN6j95gQ9V0HNOqRdRw2ZRrLNlhZDmMRJ3DjLAMdKIq7hLQBShWtWMnaxONAYoJeGN 1W3V59jXmXurmNbh0lIz3Rl7eHZK6iiej+nJtGsteQwUrlDXH5W5mdpp/0xeNfhA2Of2 JDpCKdEDk4hV7AfKFcAQ+iKcN4634Bch+gwzVpuHv8s2jV5270AUow/Zo1PHFnvCw6D6 DLow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=VchOYy/xvIndvfhwFWjIHrrlLTEcDzjOlW3vYyHU+LA=; b=CZamiSxrHYT7eE7BQhzO6nnYpHwgyArD2+GmcWMWNS+qsn+0nldzF7i0LhZedE9Eos bYMBUtyelZiXCTAMD/FdetRMQpqCg5SFMSYhQRH7YHKUmnpDe/NKxXsTWyztc2QnFIaD 8uhEcdgd1/u8DBPiKNyH2EiyC8I32XMGGF148MporTZjnaE9J561LVGqa/Z1vppNap5c z808BFHkoJGchS71ibY1TE/sCjIyVj80tX+ut/fStgsb/e02wpaVKbJdAghSOUHXbXdE sDrLo8uJ/ldTID9UP8foLjfR8Fm8eDHQYULC70ZFAsVTZ/4F9WqGFAGaIgoDLk/GFOBp 6dHQ== X-Gm-Message-State: AOPr4FX6Czs1xYCNOxOI7g21bXOf1EzBAlts4s6+gu54MARphwz7G49smfbdATKWOplOaQ== X-Received: by 10.107.44.85 with SMTP id s82mr11068044ios.90.1461167149532; Wed, 20 Apr 2016 08:45:49 -0700 (PDT) Received: from squirtle.localdomain.localdomain (184-217-42-145.pools.spcsdns.net. [184.217.42.145]) by smtp.gmail.com with ESMTPSA id m37sm3000684ioi.3.2016.04.20.08.45.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Apr 2016 08:45:49 -0700 (PDT) From: Andrey Smirnov To: linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v3 1/3] PCI: imx6: Use enum instead of bool for variant indicator Date: Wed, 20 Apr 2016 08:45:29 -0700 Message-Id: <1461167131-26025-1-git-send-email-andrew.smirnov@gmail.com> X-Mailer: git-send-email 2.5.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160420_084611_064329_559E5385 X-CRM114-Status: GOOD ( 23.78 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrey Smirnov , Richard Zhu , linux-kernel@vger.kernel.org, gary.bisson@boundarydevices.com, Bjorn Helgaas , Lucas Stach MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 Use enumerated type instead of a boolean flag to specify the variant of the PCIe IP block (6Q, 6SX, etc). This patch has zero functional impact, however it makes the code easier to extend for the case of more than 2 possible variants of an IP block (of which there are). Signed-off-by: Andrey Smirnov Reviewed-by: Fabio Estevam --- Changes since v2: - Removed default clause in all introduced switch statements - Switched to using of_device_get_match_data instead of explicit of_device_is_compatible checks - Added a mention of the new DT compatibility string in the documentation Changes since v1: - Patchset is rebased against https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/host-imx6 - DTS files changes moved into a separate patch drivers/pci/host/pci-imx6.c | 124 ++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 0f6d630..a77e7fd 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,11 @@ #define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp) +enum imx6_pcie_variants { + IMX6Q, + IMX6SX +}; + struct imx6_pcie { struct gpio_desc *reset_gpio; struct clk *pcie_bus; @@ -39,7 +45,7 @@ struct imx6_pcie { struct clk *pcie; struct pcie_port pp; struct regmap *iomuxc_gpr; - bool is_imx6sx; + enum imx6_pcie_variants variant; void __iomem *mem_base; u32 tx_deemph_gen1; u32 tx_deemph_gen2_3p5db; @@ -238,7 +244,8 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp) struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); u32 val, gpr1, gpr12; - if (imx6_pcie->is_imx6sx) { + switch (imx6_pcie->variant) { + case IMX6SX: regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6SX_GPR12_PCIE_TEST_POWERDOWN, IMX6SX_GPR12_PCIE_TEST_POWERDOWN); @@ -246,72 +253,76 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp) regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, IMX6SX_GPR5_PCIE_BTNRST_RESET, IMX6SX_GPR5_PCIE_BTNRST_RESET); - return 0; - } - - /* - * If the bootloader already enabled the link we need some special - * handling to get the core back into a state where it is safe to - * touch it for configuration. As there is no dedicated reset signal - * wired up for MX6QDL, we need to manually force LTSSM into "detect" - * state before completely disabling LTSSM, which is a prerequisite - * for core configuration. - * - * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong - * indication that the bootloader activated the link. - */ - regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1); - regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12); - - if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) && - (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) { - val = readl(pp->dbi_base + PCIE_PL_PFLR); - val &= ~PCIE_PL_PFLR_LINK_STATE_MASK; - val |= PCIE_PL_PFLR_FORCE_LINK; - writel(val, pp->dbi_base + PCIE_PL_PFLR); + break; + case IMX6Q: + /* + * If the bootloader already enabled the link we need some special + * handling to get the core back into a state where it is safe to + * touch it for configuration. As there is no dedicated reset signal + * wired up for MX6QDL, we need to manually force LTSSM into "detect" + * state before completely disabling LTSSM, which is a prerequisite + * for core configuration. + * + * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong + * indication that the bootloader activated the link. + */ + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1); + regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12); + + if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) && + (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) { + val = readl(pp->dbi_base + PCIE_PL_PFLR); + val &= ~PCIE_PL_PFLR_LINK_STATE_MASK; + val |= PCIE_PL_PFLR_FORCE_LINK; + writel(val, pp->dbi_base + PCIE_PL_PFLR); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); + } - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); + break; } - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); - return 0; } static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) { struct pcie_port *pp = &imx6_pcie->pp; - int ret; + int ret = 0; - if (imx6_pcie->is_imx6sx) { + switch (imx6_pcie->variant) { + case IMX6SX: ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); if (ret) { dev_err(pp->dev, "unable to enable pcie_axi clock\n"); - return ret; + break; } regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0); - return ret; + break; + case IMX6Q: + /* power up core phy and enable ref clock */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); + /* + * the async reset input need ref clock to sync internally, + * when the ref clock comes after reset, internal synced + * reset time is too short, cannot meet the requirement. + * add one ~10us delay here. + */ + udelay(10); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); + break; } - /* power up core phy and enable ref clock */ - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); - /* - * the async reset input need ref clock to sync internally, - * when the ref clock comes after reset, internal synced - * reset time is too short, cannot meet the requirement. - * add one ~10us delay here. - */ - udelay(10); - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); - return 0; + return ret; } static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) @@ -353,7 +364,7 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 1); } - if (imx6_pcie->is_imx6sx) + if (imx6_pcie->variant == IMX6SX) regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, IMX6SX_GPR5_PCIE_BTNRST_RESET, 0); @@ -374,11 +385,10 @@ static void imx6_pcie_init_phy(struct pcie_port *pp) { struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); - if (imx6_pcie->is_imx6sx) { + if (imx6_pcie->variant == IMX6SX) regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6SX_GPR12_PCIE_RX_EQ_MASK, IMX6SX_GPR12_PCIE_RX_EQ_2); - } regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); @@ -585,8 +595,8 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) pp = &imx6_pcie->pp; pp->dev = &pdev->dev; - imx6_pcie->is_imx6sx = of_device_is_compatible(pp->dev->of_node, - "fsl,imx6sx-pcie"); + imx6_pcie->variant = + (enum imx6_pcie_variants)of_device_get_match_data(&pdev->dev); /* Added for PCI abort handling */ hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0, @@ -623,7 +633,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev) return PTR_ERR(imx6_pcie->pcie); } - if (imx6_pcie->is_imx6sx) { + if (imx6_pcie->variant == IMX6SX) { imx6_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev, "pcie_inbound_axi"); if (IS_ERR(imx6_pcie->pcie_inbound_axi)) { @@ -679,8 +689,8 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) } static const struct of_device_id imx6_pcie_of_match[] = { - { .compatible = "fsl,imx6q-pcie", }, - { .compatible = "fsl,imx6sx-pcie", }, + { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, }, + { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, }, {}, }; MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);