forked from mirrors/linux
		
	Add RX lane margining settings for 16.0 GT/s (GEN 4) data rate. These settings improve link stability while operating at high date rates and helps to improve signal quality. Link: https://lore.kernel.org/linux-pci/20240911-pci-qcom-gen4-stability-v7-4-743f5c1fd027@linaro.org Tested-by: Johan Hovold <johan+linaro@kernel.org> Signed-off-by: Shashank Babu Chinta Venkata <quic_schintav@quicinc.com> [mani: dropped the code refactoring and minor changes] Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> [kwilczynski: commit log] Signed-off-by: Krzysztof WilczyĆski <kwilczynski@kernel.org> Reviewed-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
		
			
				
	
	
		
			78 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| /*
 | |
|  * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
 | |
|  */
 | |
| 
 | |
| #include <linux/pci.h>
 | |
| 
 | |
| #include "pcie-designware.h"
 | |
| #include "pcie-qcom-common.h"
 | |
| 
 | |
| void qcom_pcie_common_set_16gt_equalization(struct dw_pcie *pci)
 | |
| {
 | |
| 	u32 reg;
 | |
| 
 | |
| 	/*
 | |
| 	 * GEN3_RELATED_OFF register is repurposed to apply equalization
 | |
| 	 * settings at various data transmission rates through registers namely
 | |
| 	 * GEN3_EQ_*. The RATE_SHADOW_SEL bit field of GEN3_RELATED_OFF
 | |
| 	 * determines the data rate for which these equalization settings are
 | |
| 	 * applied.
 | |
| 	 */
 | |
| 	reg = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
 | |
| 	reg &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
 | |
| 	reg &= ~GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK;
 | |
| 	reg |= FIELD_PREP(GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK,
 | |
| 			  GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT);
 | |
| 	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, reg);
 | |
| 
 | |
| 	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF);
 | |
| 	reg &= ~(GEN3_EQ_FMDC_T_MIN_PHASE23 |
 | |
| 		GEN3_EQ_FMDC_N_EVALS |
 | |
| 		GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA |
 | |
| 		GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA);
 | |
| 	reg |= FIELD_PREP(GEN3_EQ_FMDC_T_MIN_PHASE23, 0x1) |
 | |
| 		FIELD_PREP(GEN3_EQ_FMDC_N_EVALS, 0xd) |
 | |
| 		FIELD_PREP(GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA, 0x5) |
 | |
| 		FIELD_PREP(GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA, 0x5);
 | |
| 	dw_pcie_writel_dbi(pci, GEN3_EQ_FB_MODE_DIR_CHANGE_OFF, reg);
 | |
| 
 | |
| 	reg = dw_pcie_readl_dbi(pci, GEN3_EQ_CONTROL_OFF);
 | |
| 	reg &= ~(GEN3_EQ_CONTROL_OFF_FB_MODE |
 | |
| 		GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE |
 | |
| 		GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL |
 | |
| 		GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC);
 | |
| 	dw_pcie_writel_dbi(pci, GEN3_EQ_CONTROL_OFF, reg);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_equalization);
 | |
| 
 | |
| void qcom_pcie_common_set_16gt_lane_margining(struct dw_pcie *pci)
 | |
| {
 | |
| 	u32 reg;
 | |
| 
 | |
| 	reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_1_OFF);
 | |
| 	reg &= ~(MARGINING_MAX_VOLTAGE_OFFSET |
 | |
| 		MARGINING_NUM_VOLTAGE_STEPS |
 | |
| 		MARGINING_MAX_TIMING_OFFSET |
 | |
| 		MARGINING_NUM_TIMING_STEPS);
 | |
| 	reg |= FIELD_PREP(MARGINING_MAX_VOLTAGE_OFFSET, 0x24) |
 | |
| 		FIELD_PREP(MARGINING_NUM_VOLTAGE_STEPS, 0x78) |
 | |
| 		FIELD_PREP(MARGINING_MAX_TIMING_OFFSET, 0x32) |
 | |
| 		FIELD_PREP(MARGINING_NUM_TIMING_STEPS, 0x10);
 | |
| 	dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_1_OFF, reg);
 | |
| 
 | |
| 	reg = dw_pcie_readl_dbi(pci, GEN4_LANE_MARGINING_2_OFF);
 | |
| 	reg |= MARGINING_IND_ERROR_SAMPLER |
 | |
| 		MARGINING_SAMPLE_REPORTING_METHOD |
 | |
| 		MARGINING_IND_LEFT_RIGHT_TIMING |
 | |
| 		MARGINING_VOLTAGE_SUPPORTED;
 | |
| 	reg &= ~(MARGINING_IND_UP_DOWN_VOLTAGE |
 | |
| 		MARGINING_MAXLANES |
 | |
| 		MARGINING_SAMPLE_RATE_TIMING |
 | |
| 		MARGINING_SAMPLE_RATE_VOLTAGE);
 | |
| 	reg |= FIELD_PREP(MARGINING_MAXLANES, pci->num_lanes) |
 | |
| 		FIELD_PREP(MARGINING_SAMPLE_RATE_TIMING, 0x3f) |
 | |
| 		FIELD_PREP(MARGINING_SAMPLE_RATE_VOLTAGE, 0x3f);
 | |
| 	dw_pcie_writel_dbi(pci, GEN4_LANE_MARGINING_2_OFF, reg);
 | |
| }
 | |
| EXPORT_SYMBOL_GPL(qcom_pcie_common_set_16gt_lane_margining);
 |