From patchwork Thu Jul 9 18:11:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 1475 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-il1-f197.google.com (mail-il1-f197.google.com [209.85.166.197]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id EDC213F062 for ; Thu, 9 Jul 2020 20:11:22 +0200 (CEST) Received: by mail-il1-f197.google.com with SMTP id o17sf1820936ilt.19 for ; Thu, 09 Jul 2020 11:11:22 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1594318281; cv=pass; d=google.com; s=arc-20160816; b=LpUbv8UmJ5suQhCKuuEROfQ5vFjLIDiuG+tSgkTmz4YAFAj4S5eIJFjOuQnlQjheBU 4QMseVk+7dj/S6UldoP0roDCrxWeL1O0ryshtcbFMGH+5KGG1rDA/V+JyPhuXJDKQpZo dcPTgxI34x1Wnq5n2bKTtEiVKBZwkZG4xwWIYWdYqnIuaQX1MqUGJwj1qABROcOUyfWg z30O4uu9nCQ96bW1yE4hxQsugVNIEij+F0wkAJBBdFX/O3r4DnHfDyN2MFWdus0dRtwQ Yh8sugLEVRkA39g3GPom+uEo30CpRU1GxBO4OFIf1tF3d/1ZgWMdJb1MR1h2hp4uIe7k lPOg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=/QN98Fgtt041sLNQDth1Q5juRaJyBZRn8IHOa5WZxiQ=; b=gcbZOxrhYap0xdBJYZITOIGS9kt4ZBCtZnL/ruUNf3qEh5YciZNe+x4hrKE1YmTXA8 anBNxEFiyYkWdqg5aJeO+AsGYFjxzvAF1FrL7si+cyYOl7wM+EkdjN7cIp1ezhjgkWpu 6RvRo+kD7qG4sw0h5WdbgR/589o/ofJo1pCrEQcIvThNHf9RNHkHMH+GmTBohooS5j3y rtWAudTCSgtFs7NLKxaTkahFfkz3O//u72JhSAdXJWD2f5QpRXGDylw4tiQ2pioMvaU4 UK7PdiN6+0ky7yBDbwjlJIzXNhdhs1EnSZHTy3wpK+tgksQH3/EvCCnPKXRkQ55T5iIM 5QZQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=H4jwzU7h; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=/QN98Fgtt041sLNQDth1Q5juRaJyBZRn8IHOa5WZxiQ=; b=fzNuDhKLP0/bcxDSgMizXvdCeBjQZXrSg7BwBcg9VlBUtXjG9NgHg1nYCGKiim4WSG mP0e7YoLK29IqaPqCk81PUHvzUh6rTXQJwyOsgguZzfK88V4UtVYwg4Uds/Bxfu5NmYr NSOziLDbuN5rZN0kKuj+Wxh08FEX+jGvkmsK4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-unsubscribe; bh=/QN98Fgtt041sLNQDth1Q5juRaJyBZRn8IHOa5WZxiQ=; b=PPD3gnTvDKdYo/4xyjWNXcKIm6S9N/m2QJng8KX594WO2jH647aaf6HyCt5WESlVwD BGocWDGC1yNqsvaRu/qoyNo8vLC/TL7QW9TRIp94wq1fvFdyGGKEk0NbjmcQx3b1MMUH 4L146YbdY5XpI/TF892m4/xBNdCfj9BAFE8HUjOogj31Vk4xhcK92dVlr6u5aH4cRtQB gZdwTWpxYELSwaoXCxIk2Fdha2lRPQDPqOVUUO+i/DecutqRmpgnPCyRD9A098xTsWGB Cm43vC0hMpacuMJhchB5wmBnXXWG2Ok7Snj7HA7VBhVkd+lKnHwNAHHNwqm8rIR45/Xa jt0w== X-Gm-Message-State: AOAM531CC2TPwaq2QfjlBf3ft9JAI18ZhjUoEHfkg2mYKct4IEJkgH9i Yq5aC6QidaoBSu/87iTdUdLujj/Z X-Google-Smtp-Source: ABdhPJzbdeQoSg55+2jVg3HoSVi8vsdffj1bBNvbClpOn5StFLq+dV73N0jK3YsvGHp0CMNEgqiyLg== X-Received: by 2002:a05:6602:1616:: with SMTP id x22mr44802023iow.70.1594318280979; Thu, 09 Jul 2020 11:11:20 -0700 (PDT) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a6b:15c6:: with SMTP id 189ls1155293iov.8.gmail; Thu, 09 Jul 2020 11:11:20 -0700 (PDT) X-Received: by 2002:a6b:d31a:: with SMTP id s26mr43787768iob.48.1594318280564; Thu, 09 Jul 2020 11:11:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594318280; cv=none; d=google.com; s=arc-20160816; b=hh8JIIZBPzGFJfBO4/kYaV+32Ar51pk4Oqe326iK7AXU4r/+AHVatib9pKBbSAaQ6A +OJSEQg/X7V+ddAFnuwSkfun897mOWrnZGEYVmCGUQSFE01Dw1jxrl6v2T+ThvwV+ToS zPXrGoObOq3O8PCRaf8iaMSZTxIBqjjqzQ0BqANj64tD3VW9WXwBy/kE4/fwr7Ca7ELT foYXg16JW/Mdk7Gx6OScSMqFaCHLSJTFibnQmu2mAGB+PhPV+60Y3K04JikW4O2wLMz6 6tLizMQuFMIhwTaAtZxKgMto/uTcNjCFZKPRGFrRX123q0VqxNucFP0xXcZRI6RMZIj2 CDyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=4IOfXaDI/O3tgp4tPqfwUYM1F7Adj8fwjzislLLHnZ0=; b=cOwKVVKSg3RYV33L9cHe9BA+k06d+LqbeggSnqzeawPXkaEEVt1zU0c5dQp3hJSbPP 2xliG3L0FnJmBd87WqfW74AQQXjvJ2V3kJYbkWr3B9I/DjoNtN9c6GSm4Hf9pP0OIcQG yr6/tPuSDNWpJjZpH75qZ35Mglkhz7Mh88Ejd8Lw5pIjEyROI/p9PgOVPYjfJRkm0rse LJG5Wts7XyBiRLUO7ABIGiAZXd6lJgfLA5tAsSjmmM4N4tNnxICJ8TlIrSmmFwtgjbKg nairbocubIxvtJ8d2p2hn0VDUT4Ov4UEZ+egKREEpCf4fb+zVVmG+Baz6NTn8j3ZKwgl ZPZg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=H4jwzU7h; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id n20sor1978837iod.91.2020.07.09.11.11.20 for (Google Transport Security); Thu, 09 Jul 2020 11:11:20 -0700 (PDT) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; X-Received: by 2002:a17:90a:254f:: with SMTP id j73mr1283176pje.16.1594318279751; Thu, 09 Jul 2020 11:11:19 -0700 (PDT) Received: from localhost.localdomain ([2405:201:c809:c7d5:a05e:bc35:5722:db76]) by smtp.gmail.com with ESMTPSA id x3sm3450696pfn.154.2020.07.09.11.11.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jul 2020 11:11:18 -0700 (PDT) From: Jagan Teki To: Kever Yang , Philipp Tomsich , Simon Glass , Shawn Lin Cc: Suniel Mahesh , U-Boot-Denx , linux-rockchip@lists.infradead.org, linux-amarula , Jagan Teki Subject: [PATCH 1/3] phy: Add Rockchip PCIe PHY driver Date: Thu, 9 Jul 2020 23:41:01 +0530 Message-Id: <20200709181103.89870-2-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200709181103.89870-1-jagan@amarulasolutions.com> References: <20200709181103.89870-1-jagan@amarulasolutions.com> MIME-Version: 1.0 X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=H4jwzU7h; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add the Rockchip PCIe PHY driver as part of Generic PHY framework. Signed-off-by: Jagan Teki Reviewed-by: Kever Yang --- drivers/phy/rockchip/Kconfig | 7 + drivers/phy/rockchip/Makefile | 1 + drivers/phy/rockchip/phy-rockchip-pcie.c | 271 +++++++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 drivers/phy/rockchip/phy-rockchip-pcie.c diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 84cc7c876d..2318e71f35 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -11,6 +11,13 @@ config PHY_ROCKCHIP_INNO_USB2 help Support for Rockchip USB2.0 PHY with Innosilicon IP block. +config PHY_ROCKCHIP_PCIE + bool "Rockchip PCIe PHY Driver" + depends on ARCH_ROCKCHIP + select PHY + help + Enable this to support the Rockchip PCIe PHY. + config PHY_ROCKCHIP_TYPEC bool "Rockchip TYPEC PHY Driver" depends on ARCH_ROCKCHIP diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile index 95b2f8a3c0..44049154f9 100644 --- a/drivers/phy/rockchip/Makefile +++ b/drivers/phy/rockchip/Makefile @@ -4,4 +4,5 @@ # obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o +obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c new file mode 100644 index 0000000000..83928cffe0 --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: (GPL-2.0-only) +/* + * Rockchip PCIe PHY driver + * + * Copyright (C) 2020 Amarula Solutions(India) + * Copyright (C) 2016 Shawn Lin + * Copyright (C) 2016 ROCKCHIP, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * The higher 16-bit of this register is used for write protection + * only if BIT(x + 16) set to 1 the BIT(x) can be written. + */ +#define HIWORD_UPDATE(val, mask, shift) \ + ((val) << (shift) | (mask) << ((shift) + 16)) + +#define PHY_MAX_LANE_NUM 4 +#define PHY_CFG_DATA_SHIFT 7 +#define PHY_CFG_ADDR_SHIFT 1 +#define PHY_CFG_DATA_MASK 0xf +#define PHY_CFG_ADDR_MASK 0x3f +#define PHY_CFG_RD_MASK 0x3ff +#define PHY_CFG_WR_ENABLE 1 +#define PHY_CFG_WR_DISABLE 1 +#define PHY_CFG_WR_SHIFT 0 +#define PHY_CFG_WR_MASK 1 +#define PHY_CFG_PLL_LOCK 0x10 +#define PHY_CFG_CLK_TEST 0x10 +#define PHY_CFG_CLK_SCC 0x12 +#define PHY_CFG_SEPE_RATE BIT(3) +#define PHY_CFG_PLL_100M BIT(3) +#define PHY_PLL_LOCKED BIT(9) +#define PHY_PLL_OUTPUT BIT(10) +#define PHY_LANE_RX_DET_SHIFT 11 +#define PHY_LANE_RX_DET_TH 0x1 +#define PHY_LANE_IDLE_OFF 0x1 +#define PHY_LANE_IDLE_MASK 0x1 +#define PHY_LANE_IDLE_A_SHIFT 3 +#define PHY_LANE_IDLE_B_SHIFT 4 +#define PHY_LANE_IDLE_C_SHIFT 5 +#define PHY_LANE_IDLE_D_SHIFT 6 + +struct rockchip_pcie_phy_data { + unsigned int pcie_conf; + unsigned int pcie_status; + unsigned int pcie_laneoff; +}; + +struct rockchip_pcie_phy { + void *reg_base; + struct clk refclk; + struct reset_ctl phy_rst; + const struct rockchip_pcie_phy_data *data; +}; + +static void phy_wr_cfg(struct rockchip_pcie_phy *priv, u32 addr, u32 data) +{ + u32 reg; + + reg = HIWORD_UPDATE(data, PHY_CFG_DATA_MASK, PHY_CFG_DATA_SHIFT); + reg |= HIWORD_UPDATE(addr, PHY_CFG_ADDR_MASK, PHY_CFG_ADDR_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_conf); + + udelay(1); + + reg = HIWORD_UPDATE(PHY_CFG_WR_ENABLE, + PHY_CFG_WR_MASK, + PHY_CFG_WR_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_conf); + + udelay(1); + + reg = HIWORD_UPDATE(PHY_CFG_WR_DISABLE, + PHY_CFG_WR_MASK, + PHY_CFG_WR_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_conf); +} + +static int rockchip_pcie_phy_power_on(struct phy *phy) +{ + struct rockchip_pcie_phy *priv = dev_get_priv(phy->dev); + int ret = 0; + u32 reg, status; + + ret = reset_deassert(&priv->phy_rst); + if (ret) { + dev_err(dev, "failed to assert phy reset\n"); + return ret; + } + + reg = HIWORD_UPDATE(PHY_CFG_PLL_LOCK, + PHY_CFG_ADDR_MASK, + PHY_CFG_ADDR_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_conf); + + reg = HIWORD_UPDATE(!PHY_LANE_IDLE_OFF, + PHY_LANE_IDLE_MASK, + PHY_LANE_IDLE_A_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_laneoff); + + ret = -EINVAL; + ret = readl_poll_sleep_timeout(priv->reg_base + priv->data->pcie_status, + status, + status & PHY_PLL_LOCKED, + 20 * 1000, + 50); + if (ret) { + dev_err(&priv->dev, "pll lock timeout!\n"); + goto err_pll_lock; + } + + phy_wr_cfg(priv, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE); + phy_wr_cfg(priv, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M); + + ret = -ETIMEDOUT; + ret = readl_poll_sleep_timeout(priv->reg_base + priv->data->pcie_status, + status, + !(status & PHY_PLL_OUTPUT), + 20 * 1000, + 50); + if (ret) { + dev_err(&priv->dev, "pll output enable timeout!\n"); + goto err_pll_lock; + } + + reg = HIWORD_UPDATE(PHY_CFG_PLL_LOCK, + PHY_CFG_ADDR_MASK, + PHY_CFG_ADDR_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_conf); + + ret = -EINVAL; + ret = readl_poll_sleep_timeout(priv->reg_base + priv->data->pcie_status, + status, + status & PHY_PLL_LOCKED, + 20 * 1000, + 50); + if (ret) { + dev_err(&priv->dev, "pll relock timeout!\n"); + goto err_pll_lock; + } + + return 0; + +err_pll_lock: + reset_assert(&priv->phy_rst); + return ret; +} + +static int rockchip_pcie_phy_power_off(struct phy *phy) +{ + struct rockchip_pcie_phy *priv = dev_get_priv(phy->dev); + int ret; + u32 reg; + + reg = HIWORD_UPDATE(PHY_LANE_IDLE_OFF, + PHY_LANE_IDLE_MASK, + PHY_LANE_IDLE_A_SHIFT); + writel(reg, priv->reg_base + priv->data->pcie_laneoff); + + ret = reset_assert(&priv->phy_rst); + if (ret) { + dev_err(dev, "failed to assert phy reset\n"); + return ret; + } + + return 0; +} + +static int rockchip_pcie_phy_init(struct phy *phy) +{ + struct rockchip_pcie_phy *priv = dev_get_priv(phy->dev); + int ret; + + ret = clk_enable(&priv->refclk); + if (ret) { + dev_err(dev, "failed to enable refclk clock\n"); + return ret; + } + + ret = reset_assert(&priv->phy_rst); + if (ret) { + dev_err(dev, "failed to assert phy reset\n"); + goto err_reset; + } + + return 0; + +err_reset: + clk_disable(&priv->refclk); + return ret; +} + +static int rockchip_pcie_phy_exit(struct phy *phy) +{ + struct rockchip_pcie_phy *priv = dev_get_priv(phy->dev); + + clk_disable(&priv->refclk); + + return 0; +} + +static struct phy_ops rockchip_pcie_phy_ops = { + .init = rockchip_pcie_phy_init, + .power_on = rockchip_pcie_phy_power_on, + .power_off = rockchip_pcie_phy_power_off, + .exit = rockchip_pcie_phy_exit, +}; + +static int rockchip_pcie_phy_probe(struct udevice *dev) +{ + struct rockchip_pcie_phy *priv = dev_get_priv(dev); + int ret; + + priv->data = (const struct rockchip_pcie_phy_data *) + dev_get_driver_data(dev); + if (!priv->data) + return -EINVAL; + + priv->reg_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + + ret = clk_get_by_name(dev, "refclk", &priv->refclk); + if (ret) { + dev_err(dev, "failed to get refclk clock phandle\n"); + return ret; + } + + ret = reset_get_by_name(dev, "phy", &priv->phy_rst); + if (ret) { + dev_err(dev, "failed to get phy reset phandle\n"); + return ret; + } + + return 0; +} + +static const struct rockchip_pcie_phy_data rk3399_pcie_data = { + .pcie_conf = 0xe220, + .pcie_status = 0xe2a4, + .pcie_laneoff = 0xe214, +}; + +static const struct udevice_id rockchip_pcie_phy_ids[] = { + { + .compatible = "rockchip,rk3399-pcie-phy", + .data = (ulong)&rk3399_pcie_data, + }, + { /* sentile */ } +}; + +U_BOOT_DRIVER(rockchip_pcie_phy) = { + .name = "rockchip_pcie_phy", + .id = UCLASS_PHY, + .of_match = rockchip_pcie_phy_ids, + .ops = &rockchip_pcie_phy_ops, + .probe = rockchip_pcie_phy_probe, + .priv_auto_alloc_size = sizeof(struct rockchip_pcie_phy), +};