forked from mirrors/linux
		
	 2a8ee61685
			
		
	
	
		2a8ee61685
		
	
	
	
	
		
			
			Don't populate const arrays on the stack, instead make them static. Makes the object code smaller by over 740 bytes. Before: text data bss dec hex filename 3840 208 0 4048 fd0 drivers/scsi/ufs/tc-dwc-g210.o After: text data bss dec hex filename 2679 624 0 3303 ce7 drivers/scsi/ufs/tc-dwc-g210.o Signed-off-by: Colin Ian King <colin.king@canonical.com> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
		
			
				
	
	
		
			320 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			320 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Synopsys G210 Test Chip driver
 | |
|  *
 | |
|  * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
 | |
|  *
 | |
|  * Authors: Joao Pinto <jpinto@synopsys.com>
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License version 2 as
 | |
|  * published by the Free Software Foundation.
 | |
|  */
 | |
| 
 | |
| #include "ufshcd.h"
 | |
| #include "unipro.h"
 | |
| 
 | |
| #include "ufshcd-dwc.h"
 | |
| #include "ufshci-dwc.h"
 | |
| #include "tc-dwc-g210.h"
 | |
| 
 | |
| /**
 | |
|  * tc_dwc_g210_setup_40bit_rmmi()
 | |
|  * This function configures Synopsys TC specific atributes (40-bit RMMI)
 | |
|  * @hba: Pointer to drivers structure
 | |
|  *
 | |
|  * Returns 0 on success or non-zero value on failure
 | |
|  */
 | |
| static int tc_dwc_g210_setup_40bit_rmmi(struct ufs_hba *hba)
 | |
| {
 | |
| 	static const struct ufshcd_dme_attr_val setup_attrs[] = {
 | |
| 		{ UIC_ARG_MIB(TX_GLOBALHIBERNATE), 0x00, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(REFCLKMODE), 0x01, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CDIRECTCTRL6), 0x80, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBDIVFACTOR), 0x08, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBDCOCTRL5), 0x64, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBPRGTUNING), 0x09, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(RTOBSERVESELECT), 0x00, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(TX_REFCLKFREQ, SELIND_LN0_TX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL, SELIND_LN0_TX), 0x19,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGEXTRATTR, SELIND_LN0_TX), 0x14,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(DITHERCTRL2, SELIND_LN0_TX), 0xd6,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RX_REFCLKFREQ, SELIND_LN0_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL, SELIND_LN0_RX), 0x19,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGWIDEINLN, SELIND_LN0_RX), 4,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN0_RX), 0x80,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(DIRECTCTRL10), 0x04, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(DIRECTCTRL19), 0x02, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN0_RX), 0x80,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG4, SELIND_LN0_RX), 0x03,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR8, SELIND_LN0_RX), 0x16,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXDIRECTCTRL2, SELIND_LN0_RX), 0x42,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG3, SELIND_LN0_RX), 0xa4,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXCALCTRL, SELIND_LN0_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG2, SELIND_LN0_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR4, SELIND_LN0_RX), 0x28,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXSQCTRL, SELIND_LN0_RX), 0x1E,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN0_RX), 0x2f,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN0_RX), 0x2f,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBPRGPLL2), 0x00, DME_LOCAL },
 | |
| 	};
 | |
| 
 | |
| 	return ufshcd_dwc_dme_set_attrs(hba, setup_attrs,
 | |
| 						ARRAY_SIZE(setup_attrs));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * tc_dwc_g210_setup_20bit_rmmi_lane0()
 | |
|  * This function configures Synopsys TC 20-bit RMMI Lane 0
 | |
|  * @hba: Pointer to drivers structure
 | |
|  *
 | |
|  * Returns 0 on success or non-zero value on failure
 | |
|  */
 | |
| static int tc_dwc_g210_setup_20bit_rmmi_lane0(struct ufs_hba *hba)
 | |
| {
 | |
| 	static const struct ufshcd_dme_attr_val setup_attrs[] = {
 | |
| 		{ UIC_ARG_MIB_SEL(TX_REFCLKFREQ, SELIND_LN0_TX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL, SELIND_LN0_TX), 0x19,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL, SELIND_LN0_RX), 0x19,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGEXTRATTR, SELIND_LN0_TX), 0x12,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(DITHERCTRL2, SELIND_LN0_TX), 0xd6,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RX_REFCLKFREQ, SELIND_LN0_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGWIDEINLN, SELIND_LN0_RX), 2,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN0_RX), 0x80,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(DIRECTCTRL10), 0x04, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(DIRECTCTRL19), 0x02, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG4, SELIND_LN0_RX), 0x03,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR8, SELIND_LN0_RX), 0x16,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXDIRECTCTRL2, SELIND_LN0_RX), 0x42,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG3, SELIND_LN0_RX), 0xa4,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXCALCTRL, SELIND_LN0_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG2, SELIND_LN0_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR4, SELIND_LN0_RX), 0x28,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXSQCTRL, SELIND_LN0_RX), 0x1E,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN0_RX), 0x2f,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBPRGPLL2), 0x00, DME_LOCAL },
 | |
| 	};
 | |
| 
 | |
| 	return ufshcd_dwc_dme_set_attrs(hba, setup_attrs,
 | |
| 						ARRAY_SIZE(setup_attrs));
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * tc_dwc_g210_setup_20bit_rmmi_lane1()
 | |
|  * This function configures Synopsys TC 20-bit RMMI Lane 1
 | |
|  * @hba: Pointer to drivers structure
 | |
|  *
 | |
|  * Returns 0 on success or non-zero value on failure
 | |
|  */
 | |
| static int tc_dwc_g210_setup_20bit_rmmi_lane1(struct ufs_hba *hba)
 | |
| {
 | |
| 	int connected_rx_lanes = 0;
 | |
| 	int connected_tx_lanes = 0;
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	static const struct ufshcd_dme_attr_val setup_tx_attrs[] = {
 | |
| 		{ UIC_ARG_MIB_SEL(TX_REFCLKFREQ, SELIND_LN1_TX), 0x0d,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL, SELIND_LN1_TX), 0x19,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGEXTRATTR, SELIND_LN1_TX), 0x12,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(DITHERCTRL2, SELIND_LN0_TX), 0xd6,
 | |
| 								DME_LOCAL },
 | |
| 	};
 | |
| 
 | |
| 	static const struct ufshcd_dme_attr_val setup_rx_attrs[] = {
 | |
| 		{ UIC_ARG_MIB_SEL(RX_REFCLKFREQ, SELIND_LN1_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL, SELIND_LN1_RX), 0x19,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGWIDEINLN, SELIND_LN1_RX), 2,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN1_RX), 0x80,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG4, SELIND_LN1_RX), 0x03,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR8, SELIND_LN1_RX), 0x16,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXDIRECTCTRL2, SELIND_LN1_RX), 0x42,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG3, SELIND_LN1_RX), 0xa4,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXCALCTRL, SELIND_LN1_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(ENARXDIRECTCFG2, SELIND_LN1_RX), 0x01,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR4, SELIND_LN1_RX), 0x28,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(RXSQCTRL, SELIND_LN1_RX), 0x1E,
 | |
| 								DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN1_RX), 0x2f,
 | |
| 								DME_LOCAL },
 | |
| 	};
 | |
| 
 | |
| 	/* Get the available lane count */
 | |
| 	ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILRXDATALANES),
 | |
| 			&connected_rx_lanes);
 | |
| 	ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILTXDATALANES),
 | |
| 			&connected_tx_lanes);
 | |
| 
 | |
| 	if (connected_tx_lanes == 2) {
 | |
| 
 | |
| 		ret = ufshcd_dwc_dme_set_attrs(hba, setup_tx_attrs,
 | |
| 						ARRAY_SIZE(setup_tx_attrs));
 | |
| 
 | |
| 		if (ret)
 | |
| 			goto out;
 | |
| 	}
 | |
| 
 | |
| 	if (connected_rx_lanes == 2) {
 | |
| 		ret = ufshcd_dwc_dme_set_attrs(hba, setup_rx_attrs,
 | |
| 						ARRAY_SIZE(setup_rx_attrs));
 | |
| 	}
 | |
| 
 | |
| out:
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * tc_dwc_g210_setup_20bit_rmmi()
 | |
|  * This function configures Synopsys TC specific atributes (20-bit RMMI)
 | |
|  * @hba: Pointer to drivers structure
 | |
|  *
 | |
|  * Returns 0 on success or non-zero value on failure
 | |
|  */
 | |
| static int tc_dwc_g210_setup_20bit_rmmi(struct ufs_hba *hba)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	static const struct ufshcd_dme_attr_val setup_attrs[] = {
 | |
| 		{ UIC_ARG_MIB(TX_GLOBALHIBERNATE), 0x00, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(REFCLKMODE), 0x01, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CDIRECTCTRL6), 0xc0, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBDIVFACTOR), 0x44, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBDCOCTRL5), 0x64, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(CBPRGTUNING), 0x09, DME_LOCAL },
 | |
| 		{ UIC_ARG_MIB(RTOBSERVESELECT), 0x00, DME_LOCAL },
 | |
| 	};
 | |
| 
 | |
| 	ret = ufshcd_dwc_dme_set_attrs(hba, setup_attrs,
 | |
| 						ARRAY_SIZE(setup_attrs));
 | |
| 	if (ret)
 | |
| 		goto out;
 | |
| 
 | |
| 	/* Lane 0 configuration*/
 | |
| 	ret = tc_dwc_g210_setup_20bit_rmmi_lane0(hba);
 | |
| 	if (ret)
 | |
| 		goto out;
 | |
| 
 | |
| 	/* Lane 1 configuration*/
 | |
| 	ret = tc_dwc_g210_setup_20bit_rmmi_lane1(hba);
 | |
| 	if (ret)
 | |
| 		goto out;
 | |
| 
 | |
| out:
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * tc_dwc_g210_config_40_bit()
 | |
|  * This function configures Local (host) Synopsys 40-bit TC specific attributes
 | |
|  *
 | |
|  * @hba: Pointer to drivers structure
 | |
|  *
 | |
|  * Returns 0 on success non-zero value on failure
 | |
|  */
 | |
| int tc_dwc_g210_config_40_bit(struct ufs_hba *hba)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	dev_info(hba->dev, "Configuring Test Chip 40-bit RMMI\n");
 | |
| 	ret = tc_dwc_g210_setup_40bit_rmmi(hba);
 | |
| 	if (ret) {
 | |
| 		dev_err(hba->dev, "Configuration failed\n");
 | |
| 		goto out;
 | |
| 	}
 | |
| 
 | |
| 	/* To write Shadow register bank to effective configuration block */
 | |
| 	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 0x01);
 | |
| 	if (ret)
 | |
| 		goto out;
 | |
| 
 | |
| 	/* To configure Debug OMC */
 | |
| 	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_DEBUGOMC), 0x01);
 | |
| 
 | |
| out:
 | |
| 	return ret;
 | |
| }
 | |
| EXPORT_SYMBOL(tc_dwc_g210_config_40_bit);
 | |
| 
 | |
| /**
 | |
|  * tc_dwc_g210_config_20_bit()
 | |
|  * This function configures Local (host) Synopsys 20-bit TC specific attributes
 | |
|  *
 | |
|  * @hba: Pointer to drivers structure
 | |
|  *
 | |
|  * Returns 0 on success non-zero value on failure
 | |
|  */
 | |
| int tc_dwc_g210_config_20_bit(struct ufs_hba *hba)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 
 | |
| 	dev_info(hba->dev, "Configuring Test Chip 20-bit RMMI\n");
 | |
| 	ret = tc_dwc_g210_setup_20bit_rmmi(hba);
 | |
| 	if (ret) {
 | |
| 		dev_err(hba->dev, "Configuration failed\n");
 | |
| 		goto out;
 | |
| 	}
 | |
| 
 | |
| 	/* To write Shadow register bank to effective configuration block */
 | |
| 	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 0x01);
 | |
| 	if (ret)
 | |
| 		goto out;
 | |
| 
 | |
| 	/* To configure Debug OMC */
 | |
| 	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_DEBUGOMC), 0x01);
 | |
| 
 | |
| out:
 | |
| 	return ret;
 | |
| }
 | |
| EXPORT_SYMBOL(tc_dwc_g210_config_20_bit);
 | |
| 
 | |
| MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
 | |
| MODULE_DESCRIPTION("Synopsys G210 Test Chip driver");
 | |
| MODULE_LICENSE("Dual BSD/GPL");
 |