From patchwork Thu Jan 27 09:13:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aswath Govindraju X-Patchwork-Id: 1584897 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=ZpxI7/6l; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jkw2X427Yz9tk5 for ; Thu, 27 Jan 2022 20:16:52 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 34E988389C; Thu, 27 Jan 2022 10:14:38 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="ZpxI7/6l"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C4E8C83107; Thu, 27 Jan 2022 10:14:18 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 2AD72837F6 for ; Thu, 27 Jan 2022 10:14:12 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=a-govindraju@ti.com Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 20R9E8Zv130032; Thu, 27 Jan 2022 03:14:08 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1643274848; bh=+s71fgYBrbXJRbyNCUX++rIwwkHPLyo8U7Zm7igca8Q=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=ZpxI7/6lVSOg4rnb6M/2rsiQMU7ST9qxUPpEc43HMn9hbnxxz+8oTRl5N0xXtO31C hi0f3N8ailmd0v8yvWsxYfK+klKXmft76TsM17fK84bCy6YA45+W+3swrqvcqu28Ut ALMVNZC9cz8bN6X2+DXdl98Bl4sWMCmVK2Gs9JJ4= Received: from DFLE113.ent.ti.com (dfle113.ent.ti.com [10.64.6.34]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 20R9E8q0119268 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 27 Jan 2022 03:14:08 -0600 Received: from DFLE107.ent.ti.com (10.64.6.28) by DFLE113.ent.ti.com (10.64.6.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14; Thu, 27 Jan 2022 03:14:08 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) by DFLE107.ent.ti.com (10.64.6.28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.14 via Frontend Transport; Thu, 27 Jan 2022 03:14:07 -0600 Received: from gsaswath-HP-ProBook-640-G5.dal.design.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 20R9D9ZN059087; Thu, 27 Jan 2022 03:14:05 -0600 From: Aswath Govindraju To: CC: , Sanket Parmar , Alan Douglas , Swapnil Jakhade , Kishon Vijay Abraham I , Tero Kristo , Vignesh Raghavendra , Aswath Govindraju Subject: [PATCH 21/25] phy: cadence: Sierra: Add support for PHY multilink configurations Date: Thu, 27 Jan 2022 14:43:04 +0530 Message-ID: <20220127091308.13179-22-a-govindraju@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220127091308.13179-1-a-govindraju@ti.com> References: <20220127091308.13179-1-a-govindraju@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean From: Swapnil Jakhade Add support for multilink configuration of Sierra PHY. Currently, maximum two links are supported. Signed-off-by: Swapnil Jakhade Signed-off-by: Aswath Govindraju --- drivers/phy/cadence/phy-cadence-sierra.c | 153 +++++++++++++++++++++-- 1 file changed, 145 insertions(+), 8 deletions(-) diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index 323cfe470bd5..43a0f6537ab6 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -29,7 +29,7 @@ #include #define NUM_SSC_MODE 3 -#define NUM_PHY_TYPE 3 +#define NUM_PHY_TYPE 4 /* PHY register offsets */ #define SIERRA_COMMON_CDB_OFFSET 0x0 @@ -183,6 +183,11 @@ (0xD000 + ((ln) * (0x800 >> (2 - (offset))))) #define SIERRA_PHY_ISO_LINK_CTRL 0xB +/* PHY PMA lane registers */ +#define SIERRA_PHY_PMA_LANE_CDB_OFFSET(ln, offset) \ + (0xF000 + ((ln) * (0x800 >> (2 - (offset))))) +#define SIERRA_PHY_PMA_XCVR_CTRL 0x000 + #define SIERRA_MACRO_ID 0x00007364 #define SIERRA_MAX_LANES 16 #define PLL_LOCK_TIME 100 @@ -288,6 +293,8 @@ struct cdns_sierra_data { u8 reg_offset_shift; struct cdns_sierra_vals *pcs_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] [NUM_SSC_MODE]; + struct cdns_sierra_vals *phy_pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] + [NUM_SSC_MODE]; struct cdns_sierra_vals *pma_cmn_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] [NUM_SSC_MODE]; struct cdns_sierra_vals *pma_ln_vals[NUM_PHY_TYPE][NUM_PHY_TYPE] @@ -306,6 +313,7 @@ struct cdns_sierra_phy { struct regmap *regmap_phy_pcs_common_cdb; struct regmap *regmap_phy_pcs_lane_cdb[SIERRA_MAX_LANES]; struct regmap *regmap_phy_pma_common_cdb; + struct regmap *regmap_phy_pma_lane_cdb[SIERRA_MAX_LANES]; struct regmap *regmap_common_cdb; struct regmap_field *macro_id_type; struct regmap_field *phy_pll_cfg_1; @@ -361,6 +369,7 @@ static int cdns_sierra_phy_init(struct phy *gphy) struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals; enum cdns_sierra_phy_type phy_type = ins->phy_type; enum cdns_sierra_ssc_mode ssc = ins->ssc_mode; + struct cdns_sierra_vals *phy_pma_ln_vals; const struct cdns_reg_pairs *reg_pairs; struct cdns_sierra_vals *pcs_cmn_vals; struct regmap *regmap = phy->regmap; @@ -368,7 +377,7 @@ static int cdns_sierra_phy_init(struct phy *gphy) int i, j; /* Initialise the PHY registers, unless auto configured */ - if (phy->autoconf) + if (phy->autoconf || phy->nsubnodes > 1) return 0; clk_set_rate(phy->input_clks[CMN_REFCLK_DIG_DIV], 25000000); @@ -384,6 +393,18 @@ static int cdns_sierra_phy_init(struct phy *gphy) regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val); } + /* PHY PMA lane registers configurations */ + phy_pma_ln_vals = init_data->phy_pma_ln_vals[phy_type][TYPE_NONE][ssc]; + if (phy_pma_ln_vals) { + reg_pairs = phy_pma_ln_vals->reg_pairs; + num_regs = phy_pma_ln_vals->num_regs; + for (i = 0; i < ins->num_lanes; i++) { + regmap = phy->regmap_phy_pma_lane_cdb[i + ins->mlane]; + for (j = 0; j < num_regs; j++) + regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val); + } + } + /* PMA common registers configurations */ pma_cmn_vals = init_data->pma_cmn_vals[phy_type][TYPE_NONE][ssc]; if (pma_cmn_vals) { @@ -417,10 +438,13 @@ static int cdns_sierra_phy_on(struct phy *gphy) u32 val; int ret; - ret = reset_control_deassert(sp->phy_rst); - if (ret) { - dev_err(dev, "Failed to take the PHY out of reset\n"); - return ret; + if (sp->nsubnodes == 1) { + /* Take the PHY out of reset */ + ret = reset_control_deassert(sp->phy_rst); + if (ret) { + dev_err(dev, "Failed to take the PHY out of reset\n"); + return ret; + } } /* Take the PHY lane group out of reset */ @@ -776,6 +800,116 @@ static int cdns_regmap_init_blocks(struct cdns_sierra_phy *sp, } sp->regmap_phy_pma_common_cdb = regmap; + for (i = 0; i < SIERRA_MAX_LANES; i++) { + block_offset = SIERRA_PHY_PMA_LANE_CDB_OFFSET(i, reg_offset_shift); + regmap = cdns_regmap_init(dev, base, block_offset, + block_offset_shift, reg_offset_shift); + if (IS_ERR(regmap)) { + dev_err(dev, "Failed to init PHY PMA lane CDB regmap\n"); + return PTR_ERR(regmap); + } + sp->regmap_phy_pma_lane_cdb[i] = regmap; + } + + return 0; +} + +static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp) +{ + const struct cdns_sierra_data *init_data = sp->init_data; + enum cdns_sierra_phy_type phy_t1, phy_t2, tmp_phy_type; + struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals; + struct cdns_sierra_vals *phy_pma_ln_vals; + const struct cdns_reg_pairs *reg_pairs; + struct cdns_sierra_vals *pcs_cmn_vals; + int i, j, node, mlane, num_lanes, ret; + enum cdns_sierra_ssc_mode ssc; + struct regmap *regmap; + u32 num_regs; + + /* Maximum 2 links (subnodes) are supported */ + if (sp->nsubnodes != 2) + return -EINVAL; + + clk_set_rate(sp->input_clks[CMN_REFCLK_DIG_DIV], 25000000); + clk_set_rate(sp->input_clks[CMN_REFCLK1_DIG_DIV], 25000000); + + /* PHY configured to use both PLL LC and LC1 */ + regmap_field_write(sp->phy_pll_cfg_1, 0x1); + + phy_t1 = sp->phys[0]->phy_type; + phy_t2 = sp->phys[1]->phy_type; + + /* + * First configure the PHY for first link with phy_t1. Get the array + * values as [phy_t1][phy_t2][ssc]. + */ + for (node = 0; node < sp->nsubnodes; node++) { + if (node == 1) { + /* + * If first link with phy_t1 is configured, then + * configure the PHY for second link with phy_t2. + * Get the array values as [phy_t2][phy_t1][ssc]. + */ + tmp_phy_type = phy_t1; + phy_t1 = phy_t2; + phy_t2 = tmp_phy_type; + } + + mlane = sp->phys[node]->mlane; + ssc = sp->phys[node]->ssc_mode; + num_lanes = sp->phys[node]->num_lanes; + + /* PHY PCS common registers configurations */ + pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc]; + if (pcs_cmn_vals) { + reg_pairs = pcs_cmn_vals->reg_pairs; + num_regs = pcs_cmn_vals->num_regs; + regmap = sp->regmap_phy_pcs_common_cdb; + for (i = 0; i < num_regs; i++) + regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val); + } + + /* PHY PMA lane registers configurations */ + phy_pma_ln_vals = init_data->phy_pma_ln_vals[phy_t1][phy_t2][ssc]; + if (phy_pma_ln_vals) { + reg_pairs = phy_pma_ln_vals->reg_pairs; + num_regs = phy_pma_ln_vals->num_regs; + for (i = 0; i < num_lanes; i++) { + regmap = sp->regmap_phy_pma_lane_cdb[i + mlane]; + for (j = 0; j < num_regs; j++) + regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val); + } + } + + /* PMA common registers configurations */ + pma_cmn_vals = init_data->pma_cmn_vals[phy_t1][phy_t2][ssc]; + if (pma_cmn_vals) { + reg_pairs = pma_cmn_vals->reg_pairs; + num_regs = pma_cmn_vals->num_regs; + regmap = sp->regmap_common_cdb; + for (i = 0; i < num_regs; i++) + regmap_write(regmap, reg_pairs[i].off, reg_pairs[i].val); + } + + /* PMA TX lane registers configurations */ + pma_ln_vals = init_data->pma_ln_vals[phy_t1][phy_t2][ssc]; + if (pma_ln_vals) { + reg_pairs = pma_ln_vals->reg_pairs; + num_regs = pma_ln_vals->num_regs; + for (i = 0; i < num_lanes; i++) { + regmap = sp->regmap_lane_cdb[i + mlane]; + for (j = 0; j < num_regs; j++) + regmap_write(regmap, reg_pairs[j].off, reg_pairs[j].val); + } + } + } + + /* Take the PHY out of reset */ + ret = reset_control_deassert(sp->phy_rst); + if (ret) + return ret; + return 0; } @@ -896,8 +1030,11 @@ static int cdns_sierra_link_probe(struct udevice *dev) sp->num_lanes += inst->num_lanes; /* If more than one subnode, configure the PHY as multilink */ - if (!sp->autoconf && sp->nsubnodes > 1) - regmap_field_write(sp->phy_pll_cfg_1, 0x1); + if (!sp->autoconf && sp->nsubnodes > 1) { + ret = cdns_sierra_phy_configure_multilink(sp); + if (ret) + return ret; + } return 0; }