From patchwork Wed Mar 24 14:06:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 1457909 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=denx.de header.i=@denx.de header.a=rsa-sha256 header.s=phobos-20191101 header.b=ChEvGJSf; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (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 ozlabs.org (Postfix) with ESMTPS id 4F598w0B8Qz9sRR for ; Thu, 25 Mar 2021 01:09:35 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9238F828C4; Wed, 24 Mar 2021 15:08:06 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1616594886; bh=OW64Hq8NDmjuDCofrmSI9wdoV+mYXnQ/UAwCcLf65jA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ChEvGJSfpYd/PZMKWG3Eo9nsmZRV+ZnRw7Xv0e8j7rwJCIZPEOawEKL9rEAd6eu2e 2cad2qjswKgLoJFt9I30JxwRSbHZvTed34gwSg6q6m/glBcrcy+2KuLs8cQNT5Kgz3 WL/ktktZARkeTkiSbSf/1kb8Hii/0HICgBLKf0UOzOXSdbp6E5R2B95cI4KVKW+EPF NZv19So+fw+3umGGdsxfv9/enV+MlLIksYimkPwDejZGq1IHZi2/2eKHopd+Erad76 zhvcT3HxjlmLiiDg1sIHBM8nfk0XNQbBbjnwFHIWUL0UL7H4soB6HUFcX1dTJjXh9a dgqktC9Y3cdxg== Received: by phobos.denx.de (Postfix, from userid 109) id 101D58285E; Wed, 24 Mar 2021 15:07:12 +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=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mout-u-204.mailbox.org (mout-u-204.mailbox.org [IPv6:2001:67c:2050:1::465:204]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 736F382816 for ; Wed, 24 Mar 2021 15:07:00 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=sr@denx.de Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:105:465:1:2:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-u-204.mailbox.org (Postfix) with ESMTPS id 4F595w1lDyzQjp9; Wed, 24 Mar 2021 15:07:00 +0100 (CET) Received: from smtp2.mailbox.org ([80.241.60.241]) by gerste.heinlein-support.de (gerste.heinlein-support.de [91.198.250.173]) (amavisd-new, port 10030) with ESMTP id SjOEPH3xge0o; Wed, 24 Mar 2021 15:06:56 +0100 (CET) From: Stefan Roese To: u-boot@lists.denx.de Cc: Nadav Haklai , =?utf-8?q?Pali_Roh=C3=A1r?= , Kostya Porotchkin , =?utf-8?q?Marek_Beh=C3=BAn?= , Grzegorz Jaszczyk , Igal Liberman , Baruch Siach Subject: [PATCH v1 13/23] phy: marvell: cp110: let the firmware perform training for XFI Date: Wed, 24 Mar 2021 15:06:39 +0100 Message-Id: <20210324150325.v1.13.I789b130b05529dc80dadcf66aef407d93595b762@changeid> In-Reply-To: <20210324140649.1413122-1-sr@denx.de> References: <20210324140649.1413122-1-sr@denx.de> MIME-Version: 1.0 X-MBO-SPAM-Probability: X-Rspamd-Score: -2.31 / 15.00 / 15.00 X-Rspamd-Queue-Id: 2A0F2181F X-Rspamd-UID: b43198 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.4 at phobos.denx.de X-Virus-Status: Clean From: Grzegorz Jaszczyk Replace the XFI training with appropriate SMC call, so the firmware will perform exact initialization. Update Stefan 2021-03-23: Move comphy_smc() function to an earlier place - necessary for the mainline merge. Signed-off-by: Grzegorz Jaszczyk Signed-off-by: Stefan Roese Reviewed-by: Igal Liberman --- drivers/phy/marvell/comphy_cp110.c | 197 +++-------------------------- 1 file changed, 18 insertions(+), 179 deletions(-) diff --git a/drivers/phy/marvell/comphy_cp110.c b/drivers/phy/marvell/comphy_cp110.c index cbfc89cb0c36..e71b70428464 100644 --- a/drivers/phy/marvell/comphy_cp110.c +++ b/drivers/phy/marvell/comphy_cp110.c @@ -28,6 +28,7 @@ DECLARE_GLOBAL_DATA_PTR; #define MV_SIP_COMPHY_POWER_ON 0x82000001 #define MV_SIP_COMPHY_POWER_OFF 0x82000002 #define MV_SIP_COMPHY_PLL_LOCK 0x82000003 +#define MV_SIP_COMPHY_XFI_TRAIN 0x82000004 /* Used to distinguish between different possible callers (U-boot/Linux) */ #define COMPHY_CALLER_UBOOT (0x1 << 21) @@ -133,90 +134,24 @@ static u32 polling_with_timeout(void __iomem *addr, u32 val, return 0; } -/* This function performs RX training for single FFE value. - * The result of the RX training is located in: - * Saved DFE values Register[10:15]. - * - * The result is returned to the caller using *result - * - * Return '1' on succsess. - * Return '0' on failure. - */ -static int comphy_cp110_test_single_ffe( - struct chip_serdes_phy_config *ptr_chip_cfg, - u32 lane, u32 ffe, u32 *result) +static int comphy_smc(u32 function_id, void __iomem *comphy_base_addr, + u32 lane, u32 mode) { - u32 mask, data, timeout; - void __iomem *hpipe_base_addr = ptr_chip_cfg->hpipe3_base_addr; - void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base_addr, lane); - void __iomem *sd_ip_addr = SD_ADDR(hpipe_base_addr, lane); - - /* Configure PRBS counters */ - mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK; - data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mask = HPIPE_PHY_TEST_DATA_MASK; - data = 0x64 << HPIPE_PHY_TEST_DATA_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask); - - mask = HPIPE_PHY_TEST_EN_MASK; - data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); - - mdelay(50); - - /* Set the FFE value */ - mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK; - data = ffe << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET; - reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); - - /* Start RX training */ - mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK; - data = 1 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask); - - /* Check the result of RX training */ - timeout = RX_TRAINING_TIMEOUT; - while (timeout) { - data = readl(sd_ip_addr + SD_EXTERNAL_STATUS1_REG); - if (data & SD_EXTERNAL_STATUS1_REG_RX_TRAIN_COMP_MASK) - break; - mdelay(1); - timeout--; - } - - if (timeout == 0) - return 0; - - if (data & SD_EXTERNAL_STATUS1_REG_RX_TRAIN_FAILED_MASK) - return 0; - - /* Stop RX training */ - mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK; - data = 0 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET; - reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask); - - /* Read the result */ - data = readl(hpipe_addr + HPIPE_SAVED_DFE_VALUES_REG); - data &= HPIPE_SAVED_DFE_VALUES_SAV_F0D_MASK; - data >>= HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET; - *result = data; - - printf("FFE = %d, result = 0x%x\n", ffe, *result); + struct pt_regs pregs = {0}; - /* Clear the PRBS counters */ - mask = HPIPE_PHY_TEST_RESET_MASK; - data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET; - mask |= HPIPE_PHY_TEST_EN_MASK; - data |= 0x0 << HPIPE_PHY_TEST_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); + pregs.regs[0] = function_id; + pregs.regs[1] = (unsigned long)comphy_base_addr; + pregs.regs[2] = lane; + pregs.regs[3] = mode; - mask = HPIPE_PHY_TEST_RESET_MASK; - data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET; - reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask); + smc_call(&pregs); - return 1; + /* + * TODO: Firmware return 0 on success, temporary map it to u-boot + * convention, but after all comphy will be reworked the convention in + * u-boot should be change and this conversion removed + */ + return pregs.regs[0] ? 0 : 1; } /* This function performs RX training for all FFE possible values. @@ -229,10 +164,6 @@ static int comphy_cp110_test_single_ffe( int comphy_cp110_sfi_rx_training(struct chip_serdes_phy_config *ptr_chip_cfg, u32 lane) { - u32 mask, data, i, rx_train_result; - u32 max_rx_train = 0, max_rx_train_index = 0; - void __iomem *hpipe_base_addr = ptr_chip_cfg->hpipe3_base_addr; - void __iomem *hpipe_addr = HPIPE_ADDR(hpipe_base_addr, lane); int ret; debug_enter(); @@ -242,107 +173,15 @@ int comphy_cp110_sfi_rx_training(struct chip_serdes_phy_config *ptr_chip_cfg, return 0; } - /* Configure SQ threshold and CDR lock */ - mask = HPIPE_SQUELCH_THRESH_IN_MASK; - data = 0xc << HPIPE_SQUELCH_THRESH_IN_OFFSET; - reg_set(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG, data, mask); - - mask = HPIPE_SQ_DEGLITCH_WIDTH_P_MASK; - data = 0xf << HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET; - mask |= HPIPE_SQ_DEGLITCH_WIDTH_N_MASK; - data |= 0xf << HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET; - mask |= HPIPE_SQ_DEGLITCH_EN_MASK; - data |= 0x1 << HPIPE_SQ_DEGLITCH_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_SQ_GLITCH_FILTER_CTRL, data, mask); - - mask = HPIPE_CDR_LOCK_DET_EN_MASK; - data = 0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET; - reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask); - - udelay(100); - - /* Determine if we have a cable attached to this comphy, if not, - * we can't perform RX training. - */ - data = readl(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG); - if (data & HPIPE_SQUELCH_DETECTED_MASK) { - pr_err("Squelsh is not detected, can't perform RX training\n"); - return 0; - } - - data = readl(hpipe_addr + HPIPE_LOOPBACK_REG); - if (!(data & HPIPE_CDR_LOCK_MASK)) { - pr_err("CDR is not locked, can't perform RX training\n"); - return 0; - } - - /* Do preparations for RX training */ - mask = HPIPE_DFE_RES_FORCE_MASK; - data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET; - reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask); - - mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK; - data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET; - mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK; - data |= 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET; - reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask); - - /* Performs RX training for all possible FFE (Feed Forward - * Equalization, possible values are 0-7). - * We update the best value reached and the FFE which gave this value. - */ - for (i = 0; i < MAX_NUM_OF_FFE; i++) { - rx_train_result = 0; - ret = comphy_cp110_test_single_ffe(ptr_chip_cfg, lane, - i, &rx_train_result); - - if (ret && (rx_train_result > max_rx_train)) { - max_rx_train = rx_train_result; - max_rx_train_index = i; - } - } - - /* If we were able to determine which FFE gives the best value, - * now we need to set it and run RX training again (only for this - * FFE). - */ - if (max_rx_train) { - ret = comphy_cp110_test_single_ffe(ptr_chip_cfg, lane, - max_rx_train_index, - &rx_train_result); - if (ret == 1) - printf("RX Training passed(FFE = %d, result = 0x%x)\n", - max_rx_train_index, rx_train_result); - } else { - pr_err("RX training failed\n"); - ret = 0; - } + /* Mode is not relevant for xfi training */ + ret = comphy_smc(MV_SIP_COMPHY_XFI_TRAIN, + ptr_chip_cfg->comphy_base_addr, lane, 0); debug_exit(); return ret; } -static int comphy_smc(u32 function_id, void __iomem *comphy_base_addr, - u32 lane, u32 mode) -{ - struct pt_regs pregs = {0}; - - pregs.regs[0] = function_id; - pregs.regs[1] = (unsigned long)comphy_base_addr; - pregs.regs[2] = lane; - pregs.regs[3] = mode; - - smc_call(&pregs); - - /* - * TODO: Firmware return 0 on success, temporary map it to u-boot - * convention, but after all comphy will be reworked the convention in - * u-boot should be change and this conversion removed - */ - return pregs.regs[0] ? 0 : 1; -} - static int comphy_sata_power_up(u32 lane, void __iomem *hpipe_base, void __iomem *comphy_base_addr, int cp_index, u32 type)