Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Synopsys G210 Test Chip driver
0004  *
0005  * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
0006  *
0007  * Authors: Joao Pinto <jpinto@synopsys.com>
0008  */
0009 
0010 #include <linux/module.h>
0011 
0012 #include <ufs/ufshcd.h>
0013 #include <ufs/unipro.h>
0014 
0015 #include "ufshcd-dwc.h"
0016 #include "ufshci-dwc.h"
0017 #include "tc-dwc-g210.h"
0018 
0019 /**
0020  * tc_dwc_g210_setup_40bit_rmmi()
0021  * This function configures Synopsys TC specific atributes (40-bit RMMI)
0022  * @hba: Pointer to drivers structure
0023  *
0024  * Returns 0 on success or non-zero value on failure
0025  */
0026 static int tc_dwc_g210_setup_40bit_rmmi(struct ufs_hba *hba)
0027 {
0028     static const struct ufshcd_dme_attr_val setup_attrs[] = {
0029         { UIC_ARG_MIB(TX_GLOBALHIBERNATE), 0x00, DME_LOCAL },
0030         { UIC_ARG_MIB(REFCLKMODE), 0x01, DME_LOCAL },
0031         { UIC_ARG_MIB(CDIRECTCTRL6), 0x80, DME_LOCAL },
0032         { UIC_ARG_MIB(CBDIVFACTOR), 0x08, DME_LOCAL },
0033         { UIC_ARG_MIB(CBDCOCTRL5), 0x64, DME_LOCAL },
0034         { UIC_ARG_MIB(CBPRGTUNING), 0x09, DME_LOCAL },
0035         { UIC_ARG_MIB(RTOBSERVESELECT), 0x00, DME_LOCAL },
0036         { UIC_ARG_MIB_SEL(TX_REFCLKFREQ, SELIND_LN0_TX), 0x01,
0037                                 DME_LOCAL },
0038         { UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL, SELIND_LN0_TX), 0x19,
0039                                 DME_LOCAL },
0040         { UIC_ARG_MIB_SEL(CFGEXTRATTR, SELIND_LN0_TX), 0x14,
0041                                 DME_LOCAL },
0042         { UIC_ARG_MIB_SEL(DITHERCTRL2, SELIND_LN0_TX), 0xd6,
0043                                 DME_LOCAL },
0044         { UIC_ARG_MIB_SEL(RX_REFCLKFREQ, SELIND_LN0_RX), 0x01,
0045                                 DME_LOCAL },
0046         { UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL, SELIND_LN0_RX), 0x19,
0047                                 DME_LOCAL },
0048         { UIC_ARG_MIB_SEL(CFGWIDEINLN, SELIND_LN0_RX), 4,
0049                                 DME_LOCAL },
0050         { UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN0_RX), 0x80,
0051                                 DME_LOCAL },
0052         { UIC_ARG_MIB(DIRECTCTRL10), 0x04, DME_LOCAL },
0053         { UIC_ARG_MIB(DIRECTCTRL19), 0x02, DME_LOCAL },
0054         { UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN0_RX), 0x80,
0055                                 DME_LOCAL },
0056         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG4, SELIND_LN0_RX), 0x03,
0057                                 DME_LOCAL },
0058         { UIC_ARG_MIB_SEL(CFGRXOVR8, SELIND_LN0_RX), 0x16,
0059                                 DME_LOCAL },
0060         { UIC_ARG_MIB_SEL(RXDIRECTCTRL2, SELIND_LN0_RX), 0x42,
0061                                 DME_LOCAL },
0062         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG3, SELIND_LN0_RX), 0xa4,
0063                                 DME_LOCAL },
0064         { UIC_ARG_MIB_SEL(RXCALCTRL, SELIND_LN0_RX), 0x01,
0065                                 DME_LOCAL },
0066         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG2, SELIND_LN0_RX), 0x01,
0067                                 DME_LOCAL },
0068         { UIC_ARG_MIB_SEL(CFGRXOVR4, SELIND_LN0_RX), 0x28,
0069                                 DME_LOCAL },
0070         { UIC_ARG_MIB_SEL(RXSQCTRL, SELIND_LN0_RX), 0x1E,
0071                                 DME_LOCAL },
0072         { UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN0_RX), 0x2f,
0073                                 DME_LOCAL },
0074         { UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN0_RX), 0x2f,
0075                                 DME_LOCAL },
0076         { UIC_ARG_MIB(CBPRGPLL2), 0x00, DME_LOCAL },
0077     };
0078 
0079     return ufshcd_dwc_dme_set_attrs(hba, setup_attrs,
0080                         ARRAY_SIZE(setup_attrs));
0081 }
0082 
0083 /**
0084  * tc_dwc_g210_setup_20bit_rmmi_lane0()
0085  * This function configures Synopsys TC 20-bit RMMI Lane 0
0086  * @hba: Pointer to drivers structure
0087  *
0088  * Returns 0 on success or non-zero value on failure
0089  */
0090 static int tc_dwc_g210_setup_20bit_rmmi_lane0(struct ufs_hba *hba)
0091 {
0092     static const struct ufshcd_dme_attr_val setup_attrs[] = {
0093         { UIC_ARG_MIB_SEL(TX_REFCLKFREQ, SELIND_LN0_TX), 0x01,
0094                                 DME_LOCAL },
0095         { UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL, SELIND_LN0_TX), 0x19,
0096                                 DME_LOCAL },
0097         { UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL, SELIND_LN0_RX), 0x19,
0098                                 DME_LOCAL },
0099         { UIC_ARG_MIB_SEL(CFGEXTRATTR, SELIND_LN0_TX), 0x12,
0100                                 DME_LOCAL },
0101         { UIC_ARG_MIB_SEL(DITHERCTRL2, SELIND_LN0_TX), 0xd6,
0102                                 DME_LOCAL },
0103         { UIC_ARG_MIB_SEL(RX_REFCLKFREQ, SELIND_LN0_RX), 0x01,
0104                                 DME_LOCAL },
0105         { UIC_ARG_MIB_SEL(CFGWIDEINLN, SELIND_LN0_RX), 2,
0106                                 DME_LOCAL },
0107         { UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN0_RX), 0x80,
0108                                 DME_LOCAL },
0109         { UIC_ARG_MIB(DIRECTCTRL10), 0x04, DME_LOCAL },
0110         { UIC_ARG_MIB(DIRECTCTRL19), 0x02, DME_LOCAL },
0111         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG4, SELIND_LN0_RX), 0x03,
0112                                 DME_LOCAL },
0113         { UIC_ARG_MIB_SEL(CFGRXOVR8, SELIND_LN0_RX), 0x16,
0114                                 DME_LOCAL },
0115         { UIC_ARG_MIB_SEL(RXDIRECTCTRL2, SELIND_LN0_RX), 0x42,
0116                                 DME_LOCAL },
0117         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG3, SELIND_LN0_RX), 0xa4,
0118                                 DME_LOCAL },
0119         { UIC_ARG_MIB_SEL(RXCALCTRL, SELIND_LN0_RX), 0x01,
0120                                 DME_LOCAL },
0121         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG2, SELIND_LN0_RX), 0x01,
0122                                 DME_LOCAL },
0123         { UIC_ARG_MIB_SEL(CFGRXOVR4, SELIND_LN0_RX), 0x28,
0124                                 DME_LOCAL },
0125         { UIC_ARG_MIB_SEL(RXSQCTRL, SELIND_LN0_RX), 0x1E,
0126                                 DME_LOCAL },
0127         { UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN0_RX), 0x2f,
0128                                 DME_LOCAL },
0129         { UIC_ARG_MIB(CBPRGPLL2), 0x00, DME_LOCAL },
0130     };
0131 
0132     return ufshcd_dwc_dme_set_attrs(hba, setup_attrs,
0133                         ARRAY_SIZE(setup_attrs));
0134 }
0135 
0136 /**
0137  * tc_dwc_g210_setup_20bit_rmmi_lane1()
0138  * This function configures Synopsys TC 20-bit RMMI Lane 1
0139  * @hba: Pointer to drivers structure
0140  *
0141  * Returns 0 on success or non-zero value on failure
0142  */
0143 static int tc_dwc_g210_setup_20bit_rmmi_lane1(struct ufs_hba *hba)
0144 {
0145     int connected_rx_lanes = 0;
0146     int connected_tx_lanes = 0;
0147     int ret = 0;
0148 
0149     static const struct ufshcd_dme_attr_val setup_tx_attrs[] = {
0150         { UIC_ARG_MIB_SEL(TX_REFCLKFREQ, SELIND_LN1_TX), 0x0d,
0151                                 DME_LOCAL },
0152         { UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL, SELIND_LN1_TX), 0x19,
0153                                 DME_LOCAL },
0154         { UIC_ARG_MIB_SEL(CFGEXTRATTR, SELIND_LN1_TX), 0x12,
0155                                 DME_LOCAL },
0156         { UIC_ARG_MIB_SEL(DITHERCTRL2, SELIND_LN0_TX), 0xd6,
0157                                 DME_LOCAL },
0158     };
0159 
0160     static const struct ufshcd_dme_attr_val setup_rx_attrs[] = {
0161         { UIC_ARG_MIB_SEL(RX_REFCLKFREQ, SELIND_LN1_RX), 0x01,
0162                                 DME_LOCAL },
0163         { UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL, SELIND_LN1_RX), 0x19,
0164                                 DME_LOCAL },
0165         { UIC_ARG_MIB_SEL(CFGWIDEINLN, SELIND_LN1_RX), 2,
0166                                 DME_LOCAL },
0167         { UIC_ARG_MIB_SEL(CFGRXCDR8, SELIND_LN1_RX), 0x80,
0168                                 DME_LOCAL },
0169         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG4, SELIND_LN1_RX), 0x03,
0170                                 DME_LOCAL },
0171         { UIC_ARG_MIB_SEL(CFGRXOVR8, SELIND_LN1_RX), 0x16,
0172                                 DME_LOCAL },
0173         { UIC_ARG_MIB_SEL(RXDIRECTCTRL2, SELIND_LN1_RX), 0x42,
0174                                 DME_LOCAL },
0175         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG3, SELIND_LN1_RX), 0xa4,
0176                                 DME_LOCAL },
0177         { UIC_ARG_MIB_SEL(RXCALCTRL, SELIND_LN1_RX), 0x01,
0178                                 DME_LOCAL },
0179         { UIC_ARG_MIB_SEL(ENARXDIRECTCFG2, SELIND_LN1_RX), 0x01,
0180                                 DME_LOCAL },
0181         { UIC_ARG_MIB_SEL(CFGRXOVR4, SELIND_LN1_RX), 0x28,
0182                                 DME_LOCAL },
0183         { UIC_ARG_MIB_SEL(RXSQCTRL, SELIND_LN1_RX), 0x1E,
0184                                 DME_LOCAL },
0185         { UIC_ARG_MIB_SEL(CFGRXOVR6, SELIND_LN1_RX), 0x2f,
0186                                 DME_LOCAL },
0187     };
0188 
0189     /* Get the available lane count */
0190     ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILRXDATALANES),
0191             &connected_rx_lanes);
0192     ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILTXDATALANES),
0193             &connected_tx_lanes);
0194 
0195     if (connected_tx_lanes == 2) {
0196 
0197         ret = ufshcd_dwc_dme_set_attrs(hba, setup_tx_attrs,
0198                         ARRAY_SIZE(setup_tx_attrs));
0199 
0200         if (ret)
0201             goto out;
0202     }
0203 
0204     if (connected_rx_lanes == 2) {
0205         ret = ufshcd_dwc_dme_set_attrs(hba, setup_rx_attrs,
0206                         ARRAY_SIZE(setup_rx_attrs));
0207     }
0208 
0209 out:
0210     return ret;
0211 }
0212 
0213 /**
0214  * tc_dwc_g210_setup_20bit_rmmi()
0215  * This function configures Synopsys TC specific atributes (20-bit RMMI)
0216  * @hba: Pointer to drivers structure
0217  *
0218  * Returns 0 on success or non-zero value on failure
0219  */
0220 static int tc_dwc_g210_setup_20bit_rmmi(struct ufs_hba *hba)
0221 {
0222     int ret = 0;
0223 
0224     static const struct ufshcd_dme_attr_val setup_attrs[] = {
0225         { UIC_ARG_MIB(TX_GLOBALHIBERNATE), 0x00, DME_LOCAL },
0226         { UIC_ARG_MIB(REFCLKMODE), 0x01, DME_LOCAL },
0227         { UIC_ARG_MIB(CDIRECTCTRL6), 0xc0, DME_LOCAL },
0228         { UIC_ARG_MIB(CBDIVFACTOR), 0x44, DME_LOCAL },
0229         { UIC_ARG_MIB(CBDCOCTRL5), 0x64, DME_LOCAL },
0230         { UIC_ARG_MIB(CBPRGTUNING), 0x09, DME_LOCAL },
0231         { UIC_ARG_MIB(RTOBSERVESELECT), 0x00, DME_LOCAL },
0232     };
0233 
0234     ret = ufshcd_dwc_dme_set_attrs(hba, setup_attrs,
0235                         ARRAY_SIZE(setup_attrs));
0236     if (ret)
0237         goto out;
0238 
0239     /* Lane 0 configuration*/
0240     ret = tc_dwc_g210_setup_20bit_rmmi_lane0(hba);
0241     if (ret)
0242         goto out;
0243 
0244     /* Lane 1 configuration*/
0245     ret = tc_dwc_g210_setup_20bit_rmmi_lane1(hba);
0246     if (ret)
0247         goto out;
0248 
0249 out:
0250     return ret;
0251 }
0252 
0253 /**
0254  * tc_dwc_g210_config_40_bit()
0255  * This function configures Local (host) Synopsys 40-bit TC specific attributes
0256  *
0257  * @hba: Pointer to drivers structure
0258  *
0259  * Returns 0 on success non-zero value on failure
0260  */
0261 int tc_dwc_g210_config_40_bit(struct ufs_hba *hba)
0262 {
0263     int ret = 0;
0264 
0265     dev_info(hba->dev, "Configuring Test Chip 40-bit RMMI\n");
0266     ret = tc_dwc_g210_setup_40bit_rmmi(hba);
0267     if (ret) {
0268         dev_err(hba->dev, "Configuration failed\n");
0269         goto out;
0270     }
0271 
0272     /* To write Shadow register bank to effective configuration block */
0273     ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 0x01);
0274     if (ret)
0275         goto out;
0276 
0277     /* To configure Debug OMC */
0278     ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_DEBUGOMC), 0x01);
0279 
0280 out:
0281     return ret;
0282 }
0283 EXPORT_SYMBOL(tc_dwc_g210_config_40_bit);
0284 
0285 /**
0286  * tc_dwc_g210_config_20_bit()
0287  * This function configures Local (host) Synopsys 20-bit TC specific attributes
0288  *
0289  * @hba: Pointer to drivers structure
0290  *
0291  * Returns 0 on success non-zero value on failure
0292  */
0293 int tc_dwc_g210_config_20_bit(struct ufs_hba *hba)
0294 {
0295     int ret = 0;
0296 
0297     dev_info(hba->dev, "Configuring Test Chip 20-bit RMMI\n");
0298     ret = tc_dwc_g210_setup_20bit_rmmi(hba);
0299     if (ret) {
0300         dev_err(hba->dev, "Configuration failed\n");
0301         goto out;
0302     }
0303 
0304     /* To write Shadow register bank to effective configuration block */
0305     ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 0x01);
0306     if (ret)
0307         goto out;
0308 
0309     /* To configure Debug OMC */
0310     ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_DEBUGOMC), 0x01);
0311 
0312 out:
0313     return ret;
0314 }
0315 EXPORT_SYMBOL(tc_dwc_g210_config_20_bit);
0316 
0317 MODULE_AUTHOR("Joao Pinto <Joao.Pinto@synopsys.com>");
0318 MODULE_DESCRIPTION("Synopsys G210 Test Chip driver");
0319 MODULE_LICENSE("Dual BSD/GPL");