From patchwork Tue Oct 15 10:20:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentine Barshak X-Patchwork-Id: 3044251 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D6B3CBF924 for ; Tue, 15 Oct 2013 10:20:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 65189201BA for ; Tue, 15 Oct 2013 10:20:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F3296202C3 for ; Tue, 15 Oct 2013 10:20:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758527Ab3JOKUQ (ORCPT ); Tue, 15 Oct 2013 06:20:16 -0400 Received: from mail-lb0-f170.google.com ([209.85.217.170]:64731 "EHLO mail-lb0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754076Ab3JOKUO (ORCPT ); Tue, 15 Oct 2013 06:20:14 -0400 Received: by mail-lb0-f170.google.com with SMTP id w7so6622248lbi.15 for ; Tue, 15 Oct 2013 03:20:13 -0700 (PDT) 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:in-reply-to :references; bh=vHrH4WjutqF7GbHJP2/DBopDvZHB76FuVOD2kQZRKCU=; b=Ac5Mk9VpzgrCKnQJdekX1doq7d6nwokxndDDJHV83IhIVcKVBqprrVz4XCDLro2iz9 eVXFFQkmboCGycMgAGrCc8gXmn7/k+n6gpJS8aOB7y2YVOwxdypnXPGiKftfc8r4HQQt LApwDLeJwtNefL/Kiyid7YG+8mLBBT4Pr2Fq4mDzRf6dNY4uQc93J7d/KTuNXDMFBvgZ iN45yyw/V6muM8rMHCUxYI+2MOd9KLALnawAx4xUBccLCsxgjypWz9B3okNyQ3r/9YWT A80+AC3bx8yyWApWsUch28LsZgHFdhEl93WIFxkbCU8hRUHwjgCZbrTgzIg5eHx92OQ4 PddQ== X-Gm-Message-State: ALoCoQnvfDV7jkE9I41RXR/ri6Tf6UC4bkc9CaVhb830A91pK+WeB38AFYWLhVUiEHNaSryL0XvP X-Received: by 10.112.172.137 with SMTP id bc9mr34790190lbc.21.1381832412853; Tue, 15 Oct 2013 03:20:12 -0700 (PDT) Received: from black.localnet ([93.100.122.208]) by mx.google.com with ESMTPSA id b6sm63943503lae.0.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 15 Oct 2013 03:20:12 -0700 (PDT) From: Valentine Barshak To: linux-sh@vger.kernel.org, linux-ide@vger.kernel.org, devicetree@vger.kernel.org Cc: Simon Horman , Magnus Damm , Vladimir Barinov , Sergei Shtylyov , Kuninori Morimoto , Laurent Pinchart , Guennadi Liakhovetski , Tejun Heo , Mark Rutland Subject: [PATCH 2/2] sata_rcar: Add R-Car Gen2 SATA PHY support Date: Tue, 15 Oct 2013 14:20:07 +0400 Message-Id: <1381832407-22541-3-git-send-email-valentine.barshak@cogentembedded.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1381832407-22541-1-git-send-email-valentine.barshak@cogentembedded.com> References: <1381832407-22541-1-git-send-email-valentine.barshak@cogentembedded.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,KHOP_BIG_TO_CC, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 R-Car Gen2 SoCs have a different PHY which is not compatible with the older R-Car H1 (R8A7779) version. This adds OF/platform device id tables and PHY initialization callbacks for the following Gen2 SoCs: * R-Car H2: R8A7790; * R-Car M2: R8A7791. PHY initialization method is chosen based on the device id. Default PHY settings are applied for Gen2 SoCs, which should suit the Gen2 boards available. The R8A7779 platform code is modified to use "sata-r8a7779" device name. Signed-off-by: Valentine Barshak --- .../devicetree/bindings/ata/sata_rcar.txt | 5 +- arch/arm/mach-shmobile/clock-r8a7779.c | 2 +- arch/arm/mach-shmobile/setup-r8a7779.c | 2 +- drivers/ata/sata_rcar.c | 118 ++++++++++++++++++--- 4 files changed, 107 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt index 0719115..d6b20a6 100644 --- a/Documentation/devicetree/bindings/ata/sata_rcar.txt +++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt @@ -1,7 +1,10 @@ * Renesas R-Car SATA Required properties: -- compatible : should contain "renesas,sata-r8a7779"; +- compatible : should contain one of the following: + - "renesas,sata-r8a7779" for R-Car H1 + - "renesas,sata-r8a7790" for R-Car H2 + - "renesas,sata-r8a7791" for R-Car M2 - reg : offset and length of the SATA registers; - interrupts : must consist of one interrupt specifier. diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index badb8b7..6593237 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -170,7 +170,7 @@ static struct clk_lookup lookups[] = { /* MSTP32 clocks */ CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */ CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */ - CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ + CLKDEV_DEV_ID("sata-r8a7779", &mstp_clks[MSTP115]), /* SATA */ CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */ diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 13049e9..6aac99e 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -438,7 +438,7 @@ static struct resource sata_resources[] = { }; static struct platform_device sata_device = { - .name = "sata_rcar", + .name = "sata-r8a7779", .id = -1, .resource = sata_resources, .num_resources = ARRAY_SIZE(sata_resources), diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index a625cc5..068d5b4 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -123,12 +124,37 @@ #define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFEUL +/* Gen2 Physical Layer Control Registers */ +#define RCAR_GEN2_PHY_CTL1_REG 0x1704 +#define RCAR_GEN2_PHY_CTL1 0x34180002 +#define RCAR_GEN2_PHY_CTL1_SS 0xC180 /* Spread Spectrum */ + +#define RCAR_GEN2_PHY_CTL2_REG 0x170C +#define RCAR_GEN2_PHY_CTL2 0x00002303 + +#define RCAR_GEN2_PHY_CTL3_REG 0x171C +#define RCAR_GEN2_PHY_CTL3 0x000B0194 + +#define RCAR_GEN2_PHY_CTL4_REG 0x1724 +#define RCAR_GEN2_PHY_CTL4 0x00030994 + +#define RCAR_GEN2_PHY_CTL5_REG 0x1740 +#define RCAR_GEN2_PHY_CTL5 0x03004001 +#define RCAR_GEN2_PHY_CTL5_DC BIT(1) /* DC connection */ +#define RCAR_GEN2_PHY_CTL5_TR BIT(2) /* Termination Resistor */ + +enum sata_rcar_type { + RCAR_GEN1_SATA, + RCAR_GEN2_SATA, +}; + struct sata_rcar_priv { void __iomem *base; struct clk *clk; + enum sata_rcar_type type; }; -static void sata_rcar_phy_initialize(struct sata_rcar_priv *priv) +static void sata_rcar_gen1_phy_preinit(struct sata_rcar_priv *priv) { void __iomem *base = priv->base; @@ -141,8 +167,8 @@ static void sata_rcar_phy_initialize(struct sata_rcar_priv *priv) iowrite32(0, base + SATAPHYRESET_REG); } -static void sata_rcar_phy_write(struct sata_rcar_priv *priv, u16 reg, u32 val, - int group) +static void sata_rcar_gen1_phy_write(struct sata_rcar_priv *priv, u16 reg, + u32 val, int group) { void __iomem *base = priv->base; int timeout; @@ -170,6 +196,29 @@ static void sata_rcar_phy_write(struct sata_rcar_priv *priv, u16 reg, u32 val, iowrite32(0, base + SATAPHYADDR_REG); } +static void sata_rcar_gen1_phy_init(struct sata_rcar_priv *priv) +{ + sata_rcar_gen1_phy_preinit(priv); + sata_rcar_gen1_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 0); + sata_rcar_gen1_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 1); + sata_rcar_gen1_phy_write(priv, SATAPCTLR3_REG, 0x0000A061, 0); + sata_rcar_gen1_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 0); + sata_rcar_gen1_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 1); + sata_rcar_gen1_phy_write(priv, SATAPCTLR4_REG, 0x28E80000, 0); +} + +static void sata_rcar_gen2_phy_init(struct sata_rcar_priv *priv) +{ + void __iomem *base = priv->base; + + iowrite32(RCAR_GEN2_PHY_CTL1, base + RCAR_GEN2_PHY_CTL1_REG); + iowrite32(RCAR_GEN2_PHY_CTL2, base + RCAR_GEN2_PHY_CTL2_REG); + iowrite32(RCAR_GEN2_PHY_CTL3, base + RCAR_GEN2_PHY_CTL3_REG); + iowrite32(RCAR_GEN2_PHY_CTL4, base + RCAR_GEN2_PHY_CTL4_REG); + iowrite32(RCAR_GEN2_PHY_CTL5 | RCAR_GEN2_PHY_CTL5_DC | + RCAR_GEN2_PHY_CTL5_TR, base + RCAR_GEN2_PHY_CTL5_REG); +} + static void sata_rcar_freeze(struct ata_port *ap) { struct sata_rcar_priv *priv = ap->host->private_data; @@ -738,13 +787,17 @@ static void sata_rcar_init_controller(struct ata_host *host) u32 val; /* reset and setup phy */ - sata_rcar_phy_initialize(priv); - sata_rcar_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 0); - sata_rcar_phy_write(priv, SATAPCTLR1_REG, 0x00200188, 1); - sata_rcar_phy_write(priv, SATAPCTLR3_REG, 0x0000A061, 0); - sata_rcar_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 0); - sata_rcar_phy_write(priv, SATAPCTLR2_REG, 0x20000000, 1); - sata_rcar_phy_write(priv, SATAPCTLR4_REG, 0x28E80000, 0); + switch (priv->type) { + case RCAR_GEN1_SATA: + sata_rcar_gen1_phy_init(priv); + break; + case RCAR_GEN2_SATA: + sata_rcar_gen2_phy_init(priv); + break; + default: + dev_warn(host->dev, "SATA phy is not initialized\n"); + break; + } /* SATA-IP reset state */ val = ioread32(base + ATAPI_CONTROL1_REG); @@ -770,8 +823,39 @@ static void sata_rcar_init_controller(struct ata_host *host) iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG); } +static struct of_device_id sata_rcar_match[] = { + /* Deprecated, "renesas,sata-r8a7779" should be used instead. */ + { + .compatible = "renesas,rcar-sata", + .data = (void *)RCAR_GEN1_SATA, + }, + { + .compatible = "renesas,sata-r8a7779", + .data = (void *)RCAR_GEN1_SATA, + }, + { + .compatible = "renesas,sata-r8a7790", + .data = (void *)RCAR_GEN2_SATA + }, + { + .compatible = "renesas,sata-r8a7791", + .data = (void *)RCAR_GEN2_SATA + }, + {}, +}; +MODULE_DEVICE_TABLE(of, sata_rcar_match); + +static const struct platform_device_id sata_rcar_id_table[] = { + { "sata-r8a7779", RCAR_GEN1_SATA }, + { "sata-r8a7790", RCAR_GEN2_SATA }, + { "sata-r8a7791", RCAR_GEN2_SATA }, + { }, +}; +MODULE_DEVICE_TABLE(platform, sata_rcar_id_table); + static int sata_rcar_probe(struct platform_device *pdev) { + const struct of_device_id *of_id; struct ata_host *host; struct sata_rcar_priv *priv; struct resource *mem; @@ -787,6 +871,12 @@ static int sata_rcar_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + of_id = of_match_device(sata_rcar_match, &pdev->dev); + if (of_id) + priv->type = (enum sata_rcar_type)of_id->data; + else + priv->type = platform_get_device_id(pdev)->driver_data; + priv->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(priv->clk)) { dev_err(&pdev->dev, "failed to get access to sata clock\n"); @@ -892,16 +982,10 @@ static const struct dev_pm_ops sata_rcar_pm_ops = { }; #endif -static struct of_device_id sata_rcar_match[] = { - { .compatible = "renesas,rcar-sata", }, /* Deprecated */ - { .compatible = "renesas,sata-r8a7779", }, - {}, -}; -MODULE_DEVICE_TABLE(of, sata_rcar_match); - static struct platform_driver sata_rcar_driver = { .probe = sata_rcar_probe, .remove = sata_rcar_remove, + .id_table = sata_rcar_id_table, .driver = { .name = DRV_NAME, .owner = THIS_MODULE,