Thread (5 messages) 5 messages, 2 authors, 2016-02-10

Re: [PATCH 2/2] add support for DWC UFS Host Controller

From: Joao Pinto <hidden>
Date: 2016-02-10 10:09:39
Also in: linux-scsi, lkml

Hi Akinobu,

Thanks for the comments!
I will put the internal functions static and check your notify suggestion.
Do you know who the maintainer of UFS is?

Thanks,
Joao

On 2/9/2016 12:05 PM, Akinobu Mita wrote:
Hi Joao,

2016-02-09 4:07 GMT+09:00 Joao Pinto [off-list ref]:
quoted
diff --git a/drivers/scsi/ufs/ufshcd-dwc.c b/drivers/scsi/ufs/ufshcd-dwc.c
new file mode 100644
index 0000000..b12b1a8
--- /dev/null
+++ b/drivers/scsi/ufs/ufshcd-dwc.c
@@ -0,0 +1,768 @@
+/*
+ * UFS Host driver for Synopsys Designware Core
+ *
+ * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
+ *
+ * Authors: Joao Pinto <jpinto-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>
+ *
+ * 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"
+
+/**
+ * ufshcd_dwc_program_clk_div()
+ * This function programs the clk divider value. This value is needed to
+ * provide 1 microsecond tick to unipro layer.
+ * @hba: Private Structure pointer
+ * @divider_val: clock divider value to be programmed
+ *
+ */
+void ufshcd_dwc_program_clk_div(struct ufs_hba *hba, u32 divider_val)
+{
+       ufshcd_writel(hba, divider_val, DWC_UFS_REG_HCLKDIV);
+}
+EXPORT_SYMBOL(ufshcd_dwc_program_clk_div);
+
+/**
+ * ufshcd_dwc_link_is_up()
+ * Check if link is up
+ * @hba: private structure poitner
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+int ufshcd_dwc_link_is_up(struct ufs_hba *hba)
+{
+       int dme_result = 0;
+
+       ufshcd_dme_get(hba, UIC_ARG_MIB(VS_POWERSTATE), &dme_result);
+
+       if (dme_result == UFSHCD_LINK_IS_UP) {
+               ufshcd_set_link_active(hba);
+               return 0;
+       }
+
+       return 1;
+}
+EXPORT_SYMBOL(ufshcd_dwc_link_is_up);
+
+/**
+ * ufshcd_dwc_connection_setup()
+ * This function configures both the local side (host) and the peer side
+ * (device) unipro attributes to establish the connection to application/
+ * cport.
+ * This function is not required if the hardware is properly configured to
+ * have this connection setup on reset. But invoking this function does no
+ * harm and should be fine even working with any ufs device.
+ *
+ * @hba: pointer to drivers private data
+ *
+ * Returns 0 on success non-zero value on failure
+ */
+int ufshcd_dwc_connection_setup(struct ufs_hba *hba)
+{
+       int ret = 0;
+
+       /* Local side Configuration */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), 1);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS), 0x6);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTMODE), 1);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 1);
+       if (ret)
+               goto out;
+
+
+       /* Peer side Configuration */
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(N_DEVICEID), 1);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), 1);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), 1);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_PEERCPORTID), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS), 0);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_CPORTFLAGS), 0x6);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_CPORTMODE), 1);
+       if (ret)
+               goto out;
+
+       ret = ufshcd_dme_peer_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), 1);
+       if (ret)
+               goto out;
+
+out:
+       return ret;
+}
+
+/**
+ * ufshcd_dwc_setup_20bit_rmmi_lane0()
+ * This function configures Synopsys MPHY 20-bit RMMI Lane 0
+ * @hba: Pointer to drivers structure
+ *
+ * Returns 0 on success or non-zero value on failure
+ */
+int ufshcd_dwc_setup_20bit_rmmi_lane0(struct ufs_hba *hba)
+{
+       int ret = 0;
+
+       /* TX Reference Clock 26MHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_REFCLKFREQ,
+                                                       SELIND_LN0_TX), 0x01);
+       if (ret)
+               goto out;
+
+       /* TX Configuration Clock Frequency Val; Divider setting */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL,
+                                                       SELIND_LN0_TX), 0x19);
+       if (ret)
+               goto out;
+
+       /* RX Configuration Clock Frequency Val; Divider setting */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL,
+                                                       SELIND_LN0_RX), 0x19);
+       if (ret)
+               goto out;
+
+       /* TX 20-bit RMMI Interface */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGEXTRATTR,
+                                                       SELIND_LN0_TX), 0x12);
+       if (ret)
+               goto out;
+
+       /* TX dither configuration */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(DITHERCTRL2,
+                                                       SELIND_LN0_TX), 0xd6);
+       if (ret)
+               goto out;
+
+       /* RX Reference Clock 26MHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_REFCLKFREQ,
+                                                       SELIND_LN0_RX), 0x01);
+       if (ret)
+               goto out;
+
+       /* RX 20-bit RMMI Interface */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGWIDEINLN,
+                                                       SELIND_LN0_RX), 2);
+       if (ret)
+               goto out;
+
+       /* RX Squelch Detector output is routed to RX hibern8 exit signal */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXCDR8,
+                                                       SELIND_LN0_RX), 0x80);
+       if (ret)
+               goto out;
+
+       /* Common block Direct Control 10 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(DIRECTCTRL10), 0x04);
+       if (ret)
+               goto out;
+
+       /* Common block Direct Control 19 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(DIRECTCTRL19), 0x02);
+       if (ret)
+               goto out;
+
+       /* ENARXDIRECTCFG4 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG4,
+                                                       SELIND_LN0_RX), 0x03);
+       if (ret)
+               goto out;
+
+       /* CFGRXOVR8 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR8,
+                                                       SELIND_LN0_RX), 0x16);
+       if (ret)
+               goto out;
+
+       /* RXDIRECTCTRL2 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXDIRECTCTRL2,
+                                                       SELIND_LN0_RX), 0x42);
+
+       if (ret)
+               goto out;
+
+       /* ENARXDIRECTCFG3 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG3,
+                                                       SELIND_LN0_RX), 0xa4);
+
+       if (ret)
+               goto out;
+
+       /* RXCALCTRL */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXCALCTRL,
+                                                       SELIND_LN0_RX), 0x01);
+       if (ret)
+               goto out;
+
+       /* ENARXDIRECTCFG2 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG2,
+                                                       SELIND_LN0_RX), 0x01);
+       if (ret)
+               goto out;
+
+       /* CFGOVR4 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR4,
+                                                       SELIND_LN0_RX), 0x28);
+       if (ret)
+               goto out;
+
+       /* RXSQCTRL */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXSQCTRL,
+                                                       SELIND_LN0_RX), 0x1E);
+       if (ret)
+               goto out;
+
+       /* CFGOVR6 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR6,
+                                                       SELIND_LN0_RX), 0x2f);
+       if (ret)
+               goto out;
+
+       /* CBPRGPLL2 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBPRGPLL2), 0x00);
+
+out:
+       return ret;
+}
+
+/**
+ * ufshcd_dwc_setup_20bit_rmmi_lane1()
+ * This function configures Synopsys MPHY 20-bit RMMI Lane 1
+ * @hba: Pointer to drivers structure
+ *
+ * Returns 0 on success or non-zero value on failure
+ */
+int ufshcd_dwc_setup_20bit_rmmi_lane1(struct ufs_hba *hba)
+{
+       int connected_rx_lanes = 0;
+       int connected_tx_lanes = 0;
+       int ret = 0;
+
+       /* Get the available lane count */
+       ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDRXDATALANES),
+                       &connected_rx_lanes);
+       ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
+                       &connected_tx_lanes);
+
+       if (connected_tx_lanes == 2) {
+
+               /* TX Reference Clock 26MHz */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_REFCLKFREQ,
+                                                       SELIND_LN1_TX), 0x0d);
+               if (ret)
+                       goto out;
+
+               /* TX Configuration Clock Frequency Val; Divider setting */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL,
+                                                       SELIND_LN1_TX), 0x19);
+               if (ret)
+                       goto out;
+
+               /* TX 20-bit RMMI Interface */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGEXTRATTR,
+                                                       SELIND_LN1_TX), 0x12);
+               if (ret)
+                       goto out;
+
+               /* TX dither configuration */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(DITHERCTRL2,
+                                                       SELIND_LN0_TX), 0xd6);
+               if (ret)
+                       goto out;
+       }
+
+       if (connected_rx_lanes == 2) {
+
+               /* RX Reference Clock 26MHz */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_REFCLKFREQ,
+                                                       SELIND_LN1_RX), 0x01);
+               if (ret)
+                       goto out;
+
+               /* RX Configuration Clock Frequency Val; Divider setting */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL,
+                                                       SELIND_LN1_RX), 0x19);
+               if (ret)
+                       goto out;
+
+               /* RX 20-bit RMMI Interface */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGWIDEINLN,
+                                                       SELIND_LN1_RX), 2);
+               if (ret)
+                       goto out;
+
+               /* RX Squelch Detector output is routed to RX hibern8 exit
+                * signal
+                */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXCDR8,
+                                                       SELIND_LN1_RX), 0x80);
+               if (ret)
+                       goto out;
+
+               /* ENARXDIRECTCFG4 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG4,
+                                                       SELIND_LN1_RX), 0x03);
+               if (ret)
+                       goto out;
+
+               /* CFGRXOVR8 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR8,
+                                                       SELIND_LN1_RX), 0x16);
+               if (ret)
+                       goto out;
+
+               /* RXDIRECTCTRL2 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXDIRECTCTRL2,
+                                                       SELIND_LN1_RX), 0x42);
+               if (ret)
+                       goto out;
+
+               /* ENARXDIRECTCFG3 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG3,
+                                                       SELIND_LN1_RX), 0xa4);
+               if (ret)
+                       goto out;
+
+               /* RXCALCTRL */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXCALCTRL,
+                                                       SELIND_LN1_RX), 0x01);
+               if (ret)
+                       goto out;
+
+               /* ENARXDIRECTCFG2 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG2,
+                                                       SELIND_LN1_RX), 0x01);
+               if (ret)
+                       goto out;
+
+               /* CFGOVR4 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR4,
+                                                       SELIND_LN1_RX), 0x28);
+               if (ret)
+                       goto out;
+
+               /* RXSQCTRL */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXSQCTRL,
+                                                       SELIND_LN1_RX), 0x1E);
+               if (ret)
+                       goto out;
+
+               /* CFGOVR6 */
+               ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR6,
+                                                       SELIND_LN1_RX), 0x2f);
+               if (ret)
+                       goto out;
+       }
+
+out:
+       return ret;
+}
+
+/**
+ * ufshcd_dwc_setup_20bit_rmmi()
+ * This function configures Synopsys MPHY specific atributes (20-bit RMMI)
+ * @hba: Pointer to drivers structure
+ *
+ * Returns 0 on success or non-zero value on failure
+ */
+int ufshcd_dwc_setup_20bit_rmmi(struct ufs_hba *hba)
+{
+       int ret = 0;
+
+       /* Common block Tx Global Hibernate Exit */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(TX_GLOBALHIBERNATE), 0x00);
+       if (ret)
+               goto out;
+
+       /* Common block Reference Clock Mode 26MHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(REFCLKMODE), 0x01);
+       if (ret)
+               goto out;
+
+       /* Common block DCO Target Frequency MAX PWM G1:9Mpbs */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CDIRECTCTRL6), 0xc0);
+       if (ret)
+               goto out;
+
+       /* Common block TX and RX Div Factor is 4 7Mbps/20 = 350KHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBDIVFACTOR), 0x44);
+       if (ret)
+               goto out;
+
+       /* Common Block DC0 Ctrl 5*/
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBDCOCTRL5), 0x64);
+       if (ret)
+               goto out;
+
+       /* Common Block Program Tunning*/
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBPRGTUNING), 0x09);
+       if (ret)
+               goto out;
+
+       /* Common Block Real Time Observe Select - for debugging */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(RTOBSERVESELECT), 0x00);
+       if (ret)
+               goto out;
+
+       /* Lane 0 configuration*/
+       ret = ufshcd_dwc_setup_20bit_rmmi_lane0(hba);
+       if (ret)
+               goto out;
+
+       /* Lane 1 configuration*/
+       ret = ufshcd_dwc_setup_20bit_rmmi_lane1(hba);
+       if (ret)
+               goto out;
+
+out:
+       return ret;
+}
+
+/**
+ * ufshcd_dwc_setup_40bit_rmmi()
+ * This function configures Synopsys MPHY specific atributes (40-bit RMMI)
+ * @hba: Pointer to drivers structure
+ *
+ * Returns 0 on success or non-zero value on failure
+ */
+int ufshcd_dwc_setup_40bit_rmmi(struct ufs_hba *hba)
+{
+       int ret = 0;
+
+       /* Common block Tx Global Hibernate Exit */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(TX_GLOBALHIBERNATE), 0x00);
+       if (ret)
+               goto out;
+
+       /* Common block Reference Clock Mode 26MHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(REFCLKMODE), 0x01);
+       if (ret)
+               goto out;
+
+       /* Common block DCO Target Frequency MAX PWM G1:7Mpbs */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CDIRECTCTRL6), 0x80);
+       if (ret)
+               goto out;
+
+       /* Common block TX and RX Div Factor is 4 7Mbps/40 = 175KHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBDIVFACTOR), 0x08);
+       if (ret)
+               goto out;
+
+       /* Common Block DC0 Ctrl 5*/
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBDCOCTRL5), 0x64);
+       if (ret)
+               goto out;
+
+       /* Common Block Program Tunning*/
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBPRGTUNING), 0x09);
+       if (ret)
+               goto out;
+
+       /* Common Block Real Time Observe Select - for debugging */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(RTOBSERVESELECT), 0x00);
+       if (ret)
+               goto out;
+
+       /* Lane 0 configuration*/
+
+       /* TX Reference Clock 26MHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_REFCLKFREQ,
+                                                       SELIND_LN0_TX), 0x01);
+       if (ret)
+               goto out;
+
+       /* TX Configuration Clock Frequency Val; Divider setting */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_CFGCLKFREQVAL,
+                                                       SELIND_LN0_TX), 0x19);
+       if (ret)
+               goto out;
+
+       /* TX 40-bit RMMI Interface */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGEXTRATTR,
+                                                       SELIND_LN0_TX), 0x14);
+       if (ret)
+               goto out;
+
+       /* TX dither configuration */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(DITHERCTRL2,
+                                                       SELIND_LN0_TX), 0xd6);
+       if (ret)
+               goto out;
+
+       /* RX Reference Clock 26MHz */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_REFCLKFREQ,
+                                                       SELIND_LN0_RX), 0x01);
+       if (ret)
+               goto out;
+
+       /* RX Configuration Clock Frequency Val; Divider setting */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_CFGCLKFREQVAL,
+                                                       SELIND_LN0_RX), 0x19);
+       if (ret)
+               goto out;
+
+       /* RX 40-bit RMMI Interface */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGWIDEINLN,
+                                                       SELIND_LN0_RX), 4);
+       if (ret)
+               goto out;
+
+       /* RX Squelch Detector output is routed to RX hibern8 exit signal */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXCDR8,
+                                                       SELIND_LN0_RX), 0x80);
+       if (ret)
+               goto out;
+
+       /* RX Squelch Detector output is routed to RX hibern8 exit signal */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXCDR8,
+                                                       SELIND_LN0_RX), 0x80);
+       if (ret)
+               goto out;
+
+       /* Common block Direct Control 10 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(DIRECTCTRL10), 0x04);
+       if (ret)
+               goto out;
+
+       /* Common block Direct Control 19 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(DIRECTCTRL19), 0x02);
+       if (ret)
+               goto out;
+
+       /* RX Squelch Detector output is routed to RX hibern8 exit signal */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXCDR8,
+                                                       SELIND_LN0_RX), 0x80);
+       if (ret)
+               goto out;
+
+       /* ENARXDIRECTCFG4 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG4,
+                                                       SELIND_LN0_RX), 0x03);
+       if (ret)
+               goto out;
+
+       /* CFGRXOVR8 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR8,
+                                                       SELIND_LN0_RX), 0x16);
+       if (ret)
+               goto out;
+
+       /* RXDIRECTCTRL2 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXDIRECTCTRL2,
+                                                       SELIND_LN0_RX), 0x42);
+       if (ret)
+               goto out;
+
+       /* ENARXDIRECTCFG3 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG3,
+                                                       SELIND_LN0_RX), 0xa4);
+       if (ret)
+               goto out;
+
+       /* RXCALCTRL */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXCALCTRL,
+                                                       SELIND_LN0_RX), 0x01);
+       if (ret)
+               goto out;
+
+       /* ENARXDIRECTCFG2 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(ENARXDIRECTCFG2,
+                                                       SELIND_LN0_RX), 0x01);
+       if (ret)
+               goto out;
+
+       /* CFGOVR4 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR4,
+                                                       SELIND_LN0_RX), 0x28);
+       if (ret)
+               goto out;
+
+       /* RXSQCTRL */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RXSQCTRL,
+                                                       SELIND_LN0_RX), 0x1E);
+       if (ret)
+               goto out;
+
+       /* CFGOVR6 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(CFGRXOVR6,
+                                                       SELIND_LN0_RX), 0x2f);
+       if (ret)
+               goto out;
+
+       /* CBPRGPLL2 */
+       ret = ufshcd_dme_set(hba, UIC_ARG_MIB(CBPRGPLL2), 0x00);
+       if (ret)
+               goto out;
+
+out:
+       return ret;
+}
+
+/**
+ * ufshcd_dwc_setup_mphy()
+ * This function configures Local (host) Synopsys MPHY specific attributes
+ *
+ * @hba: Pointer to drivers structure
+ *
+ * Returns 0 on success non-zero value on failure
+ */
+int ufshcd_dwc_setup_mphy(struct ufs_hba *hba)
+{
+       int ret = 0;
+
+#ifdef CONFIG_SCSI_UFS_DWC_40BIT_RMMI
+       dev_info(hba->dev, "Configuring MPHY 40-bit RMMI");
+       ret = ufshcd_dwc_setup_40bit_rmmi(hba);
+       if (ret) {
+               dev_err(hba->dev, "40-bit RMMI configuration failed");
+               goto out;
+       }
+#else
+#ifdef CONFIG_SCSI_UFS_DWC_20BIT_RMMI
+       dev_info(hba->dev, "Configuring MPHY 20-bit RMMI");
+       ret = ufshcd_dwc_setup_20bit_rmmi(hba);
+       if (ret) {
+               dev_err(hba->dev, "20-bit RMMI configuration failed");
+               goto out;
+       }
+#endif
+#endif
+       /* 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;
+}
These functions are only used in this file.

ufshcd_dwc_program_clk_div
ufshcd_dwc_link_is_up
ufshcd_dwc_connection_setup
ufshcd_dwc_setup_20bit_rmmi_lane0
ufshcd_dwc_setup_20bit_rmmi_lane1
ufshcd_dwc_setup_20bit_rmmi
ufshcd_dwc_setup_40bit_rmmi
ufshcd_dwc_setup_mphy

So you can make them static functions.
quoted
+/**
+ * ufshcd_dwc_configuration()
+ * UFS Host DWC specific configuration
+ * @hba: private structure poitner
+ *
+ * Returns 0 on success, non-zero value on failure
+ */
+int ufshcd_dwc_configuration(struct ufs_hba *hba)
+{
+       int ret = 0;
+
+       /* Program Clock Divider Value */
+       ufshcd_dwc_program_clk_div(hba, UFSHCD_CLK_DIV_125);
+
+#ifdef CONFIG_SCSI_UFS_DWC_MPHY_TC
+       ret = ufshcd_dwc_setup_mphy(hba);
+       if (ret) {
+               dev_err(hba->dev, "MPHY configuration failed (%d)", ret);
+               goto out;
+       }
+#endif
+       ret = ufshcd_dme_link_startup(hba);
+       if (ret) {
+               dev_err(hba->dev, "Link Startup command failed (%d)", ret);
+               goto out;
+       }
+
+       ret = ufshcd_dwc_link_is_up(hba);
+       if (ret) {
+               dev_err(hba->dev, "Link is not up");
+               goto out;
+       }
+
+       ret = ufshcd_dwc_connection_setup(hba);
+       if (ret) {
+               dev_err(hba->dev, "Connection setup failed (%d)", ret);
+               goto out;
+       }
+
+       ret = ufshcd_make_hba_operational(hba);
+       if (ret) {
+               dev_err(hba->dev, "HBA kick start failed (%d)", ret);
+               goto out;
+       }
+
+       ret = ufshcd_verify_dev_init(hba);
+       if (ret) {
+               dev_err(hba->dev, "Device init failed (%d)", ret);
+               goto out;
+       }
+
+       ret = ufshcd_complete_dev_init(hba);
+       if (ret) {
+               dev_err(hba->dev, "Device final init failed (%d)", ret);
+               goto out;
+       }
+
+       ufshcd_set_ufs_dev_active(hba);
+       hba->wlun_dev_clr_ua = false;
+
+       if (hba->ufshcd_state == UFSHCD_STATE_RESET)
+               scsi_unblock_requests(hba->host);
+
+       hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL;
+
+       scsi_scan_host(hba->host);
+
+out:
+       return ret;
+}
+EXPORT_SYMBOL(ufshcd_dwc_configuration);
Do you really need this alternative initialization by
adding new custom_probe_hba() in vops?  I think you only need to write
link_startup_notify() callback for ufs_dwc_hba_vops like below.

ufshcd_dwc_link_startup_notify(struct ufs_hba *hba,
                                enum ufs_notify_change_status status)
{
        if (status == PRE_CHANGE) {
                ufshcd_dwc_program_clk_div();
                ufshcd_dwc_setup_mphy();
        } else { /* POST_CHANGE */
                err = ufshcd_dwc_link_is_up(hba);
                if (err)
                        return err;
                ufshcd_dwc_connection_setup();
        }
}
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help