mbox series

[00/15] introduce exynosauto v9 ufs driver

Message ID 20210709065711.25195-1-chanho61.park@samsung.com
Headers show
Series introduce exynosauto v9 ufs driver | expand

Message

Chanho Park July 9, 2021, 6:56 a.m. UTC
In ExynosAuto(variant of the Exynos for automotive), the UFS Storage needs
to be accessed from multi-OS. To increase IO performance and reduce SW
complexity, we implemented UFS-IOV to support storage IO virtualization
feature on UFS.

IO virtualization increases IO performance and reduce SW complexity
with small area cost. And IO virtualization supports virtual machine
isolation for Security and Safety which are requested by Multi-OS system
such as automotive application.

Below figure is the conception of UFS-IOV architeture.

    +------+          +------+
    | OS#1 |          | OS#2 |
    +------+          +------+
       |                 |
 +------------+     +------------+
 |  Physical  |     |   Virtual  |
 |    Host    |     |    Host    |
 +------------+     +------------+
   |      |              | <-- UTP_CMD_SAP, UTP_TM_SAP
   |   +-------------------------+
   |   |    Function Arbitor     |
   |   +-------------------------+
 +-------------------------------+
 |           UTP Layer           |
 +-------------------------------+
 +-------------------------------+
 |           UIC Layer           |
 +-------------------------------+

There are two types of host controllers on the UFS host controller
that we designed.
The UFS device has a Function Arbitor that arranges commands of each host.
When each host transmits a command to the Arbitor, the Arbitor transmits it
to the UTP layer.
Physical Host(PH) support all UFSHCI functions(all SAPs) same as
conventional UFSHCI.
Virtual Host(VH) support only data transfer function(UTP_CMD_SAP and
UTP_TM_SAP).

In an environment where multiple OSs are used, the OS that has the
leadership of the system is called System OS(Dom0). This system OS uses
PH and controls error handling.

Since VH can only use less functions than PH, it is necessary to send a
request to PH for Detected Error Handling in VH. To interface among PH
and VHs, UFSHCI HW supports mailbox. PH can broadcast mail to other VH at
the same time with arguments and VH can mail to PH with arguments.
PH and VH generate interrupts when mails from PH or VH.

In this structure, the virtual host can't support some feature and need
to skip the some part of ufshcd code by using quirk.
This patchs add quirks so that the UIC command is ignored and the ufshcd
init process can be skipped for VH. Also, according to our UFS-IOV policy,

First two patches, I picked them up from Jonmin's patchset[1] and the third
patch has been dropped because we need to check it again.

[1]: https://lore.kernel.org/linux-scsi/20210527030901.88403-1-jjmin.jeong@samsung.com/

Patch 0003 ~ 0012, they are changes of exynos7 ufs driver to apply
exynosauto v9 variant and PH/VH capabilities.
Patch 0013 ~ 0015, they introduce exynosauto v9 ufs MHCI which includes
PH and VH.

Chanho Park (13):
  scsi: ufs: ufs-exynos: change pclk available max value
  scsi: ufs: ufs-exynos: simplify drv_data retrieval
  scsi: ufs: ufs-exynos: get sysreg regmap for io-coherency
  scsi: ufs: ufs-exynos: add refclkout_stop control
  scsi: ufs: ufs-exynos: add setup_clocks callback
  scsi: ufs: ufs-exynos: correct timeout value setting registers
  scsi: ufs: ufs-exynos: support custom version of ufs_hba_variant_ops
  scsi: ufs: ufs-exynos: add EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR option
  scsi: ufs: ufs-exynos: factor out priv data init
  scsi: ufs: ufs-exynos: add pre/post_hce_enable drv callbacks
  scsi: ufs: ufs-exynos: support exynosauto v9 ufs driver
  scsi: ufs: ufs-exynos: multi-host configuration for exynosauto
  scsi: ufs: ufs-exynos: introduce exynosauto v9 virtual host

jongmin jeong (2):
  scsi: ufs: add quirk to handle broken UIC command
  scsi: ufs: add quirk to enable host controller without interface
    configuration

 drivers/scsi/ufs/ufs-exynos.c | 318 +++++++++++++++++++++++++++++++---
 drivers/scsi/ufs/ufs-exynos.h |  10 +-
 drivers/scsi/ufs/ufshcd.c     |   6 +
 drivers/scsi/ufs/ufshcd.h     |  12 ++
 4 files changed, 320 insertions(+), 26 deletions(-)

Comments

Krzysztof Kozlowski July 13, 2021, 10:57 a.m. UTC | #1
-On Fri, 9 Jul 2021 at 08:59, Chanho Park <chanho61.park@samsung.com> wrote:
>
> This patch adds to support ufs variant for ExynosAuto v9 SoC. This
> requires control UFS IP sharability register via syscon and regmap.
> Regarding uic_attr, most of values can be shared with exynos7 except
> tx_dif_p_nsec value.
>
> Signed-off-by: Chanho Park <chanho61.park@samsung.com>
> ---
>  drivers/scsi/ufs/ufs-exynos.c | 97 +++++++++++++++++++++++++++++++++++
>  1 file changed, 97 insertions(+)
>
> diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
> index 9669afe8f1f4..82f915f7a447 100644
> --- a/drivers/scsi/ufs/ufs-exynos.c
> +++ b/drivers/scsi/ufs/ufs-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/regmap.h>
>
>  #include "ufshcd.h"
>  #include "ufshcd-pltfrm.h"
> @@ -76,6 +77,12 @@
>                                  UIC_TRANSPORT_NO_CONNECTION_RX |\
>                                  UIC_TRANSPORT_BAD_TC)
>
> +/* FSYS UFS Sharability */

Sharability -> Shareability

> +#define UFS_WR_SHARABLE                BIT(2)
> +#define UFS_RD_SHARABLE                BIT(1)
> +#define UFS_SHARABLE           (UFS_WR_SHARABLE | UFS_RD_SHARABLE)
> +#define UFS_SHARABILITY_OFFSET 0x710
> +
>  enum {
>         UNIPRO_L1_5 = 0,/* PHY Adapter */
>         UNIPRO_L2,      /* Data Link */
> @@ -151,6 +158,80 @@ static int exynos7_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
>         return 0;
>  }
>
> +static int exynosauto_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
> +{
> +       struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
> +
> +       /* IO Coherency setting */
> +       if (ufs->sysreg) {
> +               return regmap_update_bits(ufs->sysreg, UFS_SHARABILITY_OFFSET,
> +                                         UFS_SHARABLE, UFS_SHARABLE);
> +       }
> +
> +       attr->tx_dif_p_nsec = 3200000;
> +
> +       return 0;
> +}
> +
> +static int exynosauto_ufs_pre_link(struct exynos_ufs *ufs)
> +{
> +       struct ufs_hba *hba = ufs->hba;
> +       int i;
> +
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
> +       for_each_ufs_rx_lane(ufs, i) {
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i),
> +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, i), 0x0);
> +
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);
> +
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);
> +
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x79);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);
> +       }
> +
> +       for_each_ufs_tx_lane(ufs, i) {
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, i),
> +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, i), 0x02);
> +
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, i), 0x8);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, i), 0x22);
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, i), 0x8);
> +
> +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 0x1);
> +       }
> +
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
> +
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
> +
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(0xa011), 0x8000);
> +
> +       return 0;
> +}
> +
> +static int exynosauto_ufs_pre_pwr_change(struct exynos_ufs *ufs,
> +                                        struct ufs_pa_layer_attr *pwr)
> +{
> +       struct ufs_hba *hba = ufs->hba;
> +
> +       /* PACP_PWR_req and delivered to the remote DME */
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
> +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
> +
> +       return 0;
> +}
> +

No need for double line.

> +
>  static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
>  {
>         struct ufs_hba *hba = ufs->hba;
> @@ -1305,6 +1386,20 @@ static struct exynos_ufs_uic_attr exynos7_uic_attr = {
>         .pa_dbg_option_suite            = 0x30103,
>  };
>
> +static struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
> +       .uic_attr               = &exynos7_uic_attr,
> +       .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
> +                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
> +                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
> +                                 UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,
> +       .opts                   = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
> +                                 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
> +                                 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
> +       .drv_init               = exynosauto_ufs_drv_init,
> +       .pre_link               = exynosauto_ufs_pre_link,
> +       .pre_pwr_change         = exynosauto_ufs_pre_pwr_change,
> +};
> +
>  static struct exynos_ufs_drv_data exynos_ufs_drvs = {
>         .uic_attr               = &exynos7_uic_attr,
>         .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
> @@ -1330,6 +1425,8 @@ static struct exynos_ufs_drv_data exynos_ufs_drvs = {
>  static const struct of_device_id exynos_ufs_of_match[] = {
>         { .compatible = "samsung,exynos7-ufs",
>           .data       = &exynos_ufs_drvs },
> +       { .compatible = "samsung,exynosautov9-ufs",
> +         .data       = &exynosauto_ufs_drvs },

This compatible is not documented. It seems that no one document
exynos7-ufs but that's not an excuse. :)

Best regards,
Krzysztof
Chanho Park July 13, 2021, 12:07 p.m. UTC | #2
> > +/* FSYS UFS Sharability */
> 
> Sharability -> Shareability

Typo. I'll correct it next patchset.

> 
> > +#define UFS_WR_SHARABLE                BIT(2)
> > +#define UFS_RD_SHARABLE                BIT(1)
> > +#define UFS_SHARABLE           (UFS_WR_SHARABLE | UFS_RD_SHARABLE)
> > +#define UFS_SHARABILITY_OFFSET 0x710
> > +
> >  enum {
> >         UNIPRO_L1_5 = 0,/* PHY Adapter */
> >         UNIPRO_L2,      /* Data Link */
> > @@ -151,6 +158,80 @@ static int exynos7_ufs_drv_init(struct device *dev,
> struct exynos_ufs *ufs)
> >         return 0;
> >  }
> >
> > +static int exynosauto_ufs_drv_init(struct device *dev, struct
> > +exynos_ufs *ufs) {
> > +       struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
> > +
> > +       /* IO Coherency setting */
> > +       if (ufs->sysreg) {
> > +               return regmap_update_bits(ufs->sysreg,
> UFS_SHARABILITY_OFFSET,
> > +                                         UFS_SHARABLE, UFS_SHARABLE);
> > +       }
> > +
> > +       attr->tx_dif_p_nsec = 3200000;
> > +
> > +       return 0;
> > +}
> > +
> > +static int exynosauto_ufs_pre_link(struct exynos_ufs *ufs) {
> > +       struct ufs_hba *hba = ufs->hba;
> > +       int i;
> > +
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
> > +       for_each_ufs_rx_lane(ufs, i) {
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i),
> > +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, i), 0x0);
> > +
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);
> > +
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);
> > +
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x79);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);
> > +       }
> > +
> > +       for_each_ufs_tx_lane(ufs, i) {
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, i),
> > +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, i), 0x02);
> > +
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, i), 0x8);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, i), 0x22);
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, i), 0x8);
> > +
> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 0x1);
> > +       }
> > +
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
> > +
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
> > +
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0xa011), 0x8000);
> > +
> > +       return 0;
> > +}
> > +
> > +static int exynosauto_ufs_pre_pwr_change(struct exynos_ufs *ufs,
> > +                                        struct ufs_pa_layer_attr
> > +*pwr) {
> > +       struct ufs_hba *hba = ufs->hba;
> > +
> > +       /* PACP_PWR_req and delivered to the remote DME */
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
> > +
> > +       return 0;
> > +}
> > +
> 
> No need for double line.

Will be fixed as well. :)

> 
> > +
> >  static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)  {
> >         struct ufs_hba *hba = ufs->hba; @@ -1305,6 +1386,20 @@ static
> > struct exynos_ufs_uic_attr exynos7_uic_attr = {
> >         .pa_dbg_option_suite            = 0x30103,
> >  };
> >
> > +static struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
> > +       .uic_attr               = &exynos7_uic_attr,
> > +       .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
> > +                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
> > +                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
> > +                                 UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,
> > +       .opts                   = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
> > +                                 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
> > +                                 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
> > +       .drv_init               = exynosauto_ufs_drv_init,
> > +       .pre_link               = exynosauto_ufs_pre_link,
> > +       .pre_pwr_change         = exynosauto_ufs_pre_pwr_change,
> > +};
> > +
> >  static struct exynos_ufs_drv_data exynos_ufs_drvs = {
> >         .uic_attr               = &exynos7_uic_attr,
> >         .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
> > @@ -1330,6 +1425,8 @@ static struct exynos_ufs_drv_data
> > exynos_ufs_drvs = {  static const struct of_device_id
> exynos_ufs_of_match[] = {
> >         { .compatible = "samsung,exynos7-ufs",
> >           .data       = &exynos_ufs_drvs },
> > +       { .compatible = "samsung,exynosautov9-ufs",
> > +         .data       = &exynosauto_ufs_drvs },
> 
> This compatible is not documented. It seems that no one document exynos7-
> ufs but that's not an excuse. :)

Hmm. Let me check whether I can add ufs-exynos.yaml.

Best Regards,
Chanho Park
Alim Akhtar July 13, 2021, 12:11 p.m. UTC | #3
> -----Original Message-----

> From: Krzysztof Kozlowski <krzk@kernel.org>

> Sent: 13 July 2021 16:28

> To: Chanho Park <chanho61.park@samsung.com>

> Cc: Alim Akhtar <alim.akhtar@samsung.com>; James E . J . Bottomley

> <jejb@linux.ibm.com>; Martin K . Petersen <martin.petersen@oracle.com>;

> Can Guo <cang@codeaurora.org>; Jaegeuk Kim <jaegeuk@kernel.org>;

> Kiwoong Kim <kwmad.kim@samsung.com>; Avri Altman

> <avri.altman@wdc.com>; Adrian Hunter <adrian.hunter@intel.com>;

> Christoph Hellwig <hch@infradead.org>; Bart Van Assche

> <bvanassche@acm.org>; jongmin jeong <jjmin.jeong@samsung.com>;

> Gyunghoon Kwon <goodjob.kwon@samsung.com>; linux-samsung-

> soc@vger.kernel.org; linux-scsi@vger.kernel.org

> Subject: Re: [PATCH 13/15] scsi: ufs: ufs-exynos: support exynosauto v9 ufs

> driver

> 

> -On Fri, 9 Jul 2021 at 08:59, Chanho Park <chanho61.park@samsung.com>

> wrote:

> >

> > This patch adds to support ufs variant for ExynosAuto v9 SoC. This

> > requires control UFS IP sharability register via syscon and regmap.

> > Regarding uic_attr, most of values can be shared with exynos7 except

> > tx_dif_p_nsec value.

> >

> > Signed-off-by: Chanho Park <chanho61.park@samsung.com>

> > ---

> >  drivers/scsi/ufs/ufs-exynos.c | 97

> > +++++++++++++++++++++++++++++++++++

> >  1 file changed, 97 insertions(+)

> >

> > diff --git a/drivers/scsi/ufs/ufs-exynos.c

> > b/drivers/scsi/ufs/ufs-exynos.c index 9669afe8f1f4..82f915f7a447

> > 100644

> > --- a/drivers/scsi/ufs/ufs-exynos.c

> > +++ b/drivers/scsi/ufs/ufs-exynos.c

> > @@ -15,6 +15,7 @@

> >  #include <linux/mfd/syscon.h>

> >  #include <linux/phy/phy.h>

> >  #include <linux/platform_device.h>

> > +#include <linux/regmap.h>

> >

> >  #include "ufshcd.h"

> >  #include "ufshcd-pltfrm.h"

> > @@ -76,6 +77,12 @@

> >                                  UIC_TRANSPORT_NO_CONNECTION_RX |\

> >                                  UIC_TRANSPORT_BAD_TC)

> >

> > +/* FSYS UFS Sharability */

> 

> Sharability -> Shareability

> 

> > +#define UFS_WR_SHARABLE                BIT(2)

> > +#define UFS_RD_SHARABLE                BIT(1)

> > +#define UFS_SHARABLE           (UFS_WR_SHARABLE | UFS_RD_SHARABLE)

> > +#define UFS_SHARABILITY_OFFSET 0x710

> > +

> >  enum {

> >         UNIPRO_L1_5 = 0,/* PHY Adapter */

> >         UNIPRO_L2,      /* Data Link */

> > @@ -151,6 +158,80 @@ static int exynos7_ufs_drv_init(struct device *dev,

> struct exynos_ufs *ufs)

> >         return 0;

> >  }

> >

> > +static int exynosauto_ufs_drv_init(struct device *dev, struct

> > +exynos_ufs *ufs) {

> > +       struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;

> > +

> > +       /* IO Coherency setting */

> > +       if (ufs->sysreg) {

> > +               return regmap_update_bits(ufs->sysreg,

> UFS_SHARABILITY_OFFSET,

> > +                                         UFS_SHARABLE, UFS_SHARABLE);

> > +       }

> > +

> > +       attr->tx_dif_p_nsec = 3200000;

> > +

> > +       return 0;

> > +}

> > +

> > +static int exynosauto_ufs_pre_link(struct exynos_ufs *ufs) {

> > +       struct ufs_hba *hba = ufs->hba;

> > +       int i;

> > +

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);

> > +       for_each_ufs_rx_lane(ufs, i) {

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i),

> > +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, i), 0x0);

> > +

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);

> > +

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);

> > +

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x79);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);

> > +       }

> > +

> > +       for_each_ufs_tx_lane(ufs, i) {

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, i),

> > +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, i), 0x02);

> > +

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, i), 0x8);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, i), 0x22);

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, i), 0x8);

> > +

> > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 0x1);

> > +       }

> > +

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);

> > +

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE),

> 0x0);

> > +

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0xa011), 0x8000);

> > +

> > +       return 0;

> > +}

> > +

> > +static int exynosauto_ufs_pre_pwr_change(struct exynos_ufs *ufs,

> > +                                        struct ufs_pa_layer_attr

> > +*pwr) {

> > +       struct ufs_hba *hba = ufs->hba;

> > +

> > +       /* PACP_PWR_req and delivered to the remote DME */

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0),

> 12000);

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1),

> 32000);

> > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2),

> 16000);

> > +

> > +       return 0;

> > +}

> > +

> 

> No need for double line.

> 

> > +

> >  static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)  {

> >         struct ufs_hba *hba = ufs->hba; @@ -1305,6 +1386,20 @@ static

> > struct exynos_ufs_uic_attr exynos7_uic_attr = {

> >         .pa_dbg_option_suite            = 0x30103,

> >  };

> >

> > +static struct exynos_ufs_drv_data exynosauto_ufs_drvs = {

> > +       .uic_attr               = &exynos7_uic_attr,

> > +       .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |

> > +                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |

> > +                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |

> > +                                 UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,

> > +       .opts                   = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |

> > +                                 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |

> > +                                 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,

> > +       .drv_init               = exynosauto_ufs_drv_init,

> > +       .pre_link               = exynosauto_ufs_pre_link,

> > +       .pre_pwr_change         = exynosauto_ufs_pre_pwr_change,

> > +};

> > +

> >  static struct exynos_ufs_drv_data exynos_ufs_drvs = {

> >         .uic_attr               = &exynos7_uic_attr,

> >         .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |

> > @@ -1330,6 +1425,8 @@ static struct exynos_ufs_drv_data

> > exynos_ufs_drvs = {  static const struct of_device_id

> exynos_ufs_of_match[] = {

> >         { .compatible = "samsung,exynos7-ufs",

> >           .data       = &exynos_ufs_drvs },

> > +       { .compatible = "samsung,exynosautov9-ufs",

> > +         .data       = &exynosauto_ufs_drvs },

> 

> This compatible is not documented. It seems that no one document

> exynos7-ufs but that's not an excuse. :)

> 

I was post along with UFS driver [1], had Rob's Reviewed-by as well, not sure why it is not merged. 
Let me ping Rob on this.
[1] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2176074.html

> Best regards,

> Krzysztof
Alim Akhtar July 13, 2021, 6:10 p.m. UTC | #4
Hi Chanho

> -----Original Message-----

> From: Chanho Park <chanho61.park@samsung.com>

> Sent: 09 July 2021 12:27

> To: Alim Akhtar <alim.akhtar@samsung.com>; James E . J . Bottomley

> <jejb@linux.ibm.com>; Martin K . Petersen <martin.petersen@oracle.com>

> Cc: Can Guo <cang@codeaurora.org>; Jaegeuk Kim <jaegeuk@kernel.org>;

> Kiwoong Kim <kwmad.kim@samsung.com>; Avri Altman

> <avri.altman@wdc.com>; Adrian Hunter <adrian.hunter@intel.com>;

> Christoph Hellwig <hch@infradead.org>; Bart Van Assche

> <bvanassche@acm.org>; jongmin jeong <jjmin.jeong@samsung.com>;

> Gyunghoon Kwon <goodjob.kwon@samsung.com>; linux-samsung-

> soc@vger.kernel.org; linux-scsi@vger.kernel.org; Chanho Park

> <chanho61.park@samsung.com>

> Subject: [PATCH 02/15] scsi: ufs: add quirk to enable host controller without

> interface configuration

> 

> From: jongmin jeong <jjmin.jeong@samsung.com>

> 

> samsung ExynosAuto SoC has two types of host controller interface to

> support the virtualization of UFS Device.

> One is the physical host(PH) that the same as conventaional UFSHCI, and the

> other is the virtual host(VH) that support data transfer function only.

> 

> In this structure, the virtual host does not support like device management.

> This patch skips the interface configuration part that cannot be performed in

> the virtual host.

> 

> Signed-off-by: jongmin jeong <jjmin.jeong@samsung.com>

> Signed-off-by: Chanho Park <chanho61.park@samsung.com>

> ---

>  drivers/scsi/ufs/ufshcd.c | 3 +++

>  drivers/scsi/ufs/ufshcd.h | 6 ++++++

>  2 files changed, 9 insertions(+)

> 

> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index

> 9702086e9860..3451b335f2b4 100644

> --- a/drivers/scsi/ufs/ufshcd.c

> +++ b/drivers/scsi/ufs/ufshcd.c

> @@ -7988,6 +7988,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba,

> bool async)

>  	if (ret)

>  		goto out;

> 

> +	if (hba->quirks &

> UFSHCD_QUIRK_SKIP_INTERFACE_CONFIGURATION)

> +		goto out;

> +

>  	/* Debug counters initialization */

>  	ufshcd_clear_dbg_ufs_stats(hba);

> 

> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index

> e67b1fcfe1a2..fe523cbd68dd 100644

> --- a/drivers/scsi/ufs/ufshcd.h

> +++ b/drivers/scsi/ufs/ufshcd.h

> @@ -573,6 +573,12 @@ enum ufshcd_quirks {

>  	 * support UIC command

>  	 */

>  	UFSHCD_QUIRK_BROKEN_UIC_CMD			= 1 << 15,

> +

> +	/*

> +	 * This quirk needs to be enabled if the host controller cannot

> +	 * support interface configuration.

> +	 */

> +	UFSHCD_QUIRK_SKIP_INTERFACE_CONFIGURATION	= 1 << 16,

May be UFSHCD_QUIRK_SKIP_PH_CONFIGURATION

>  };

> 

>  enum ufshcd_caps {

> --

> 2.32.0
Alim Akhtar July 14, 2021, 1:41 a.m. UTC | #5
Hi Chanho

> -----Original Message-----
> From: Chanho Park <chanho61.park@samsung.com>
> Sent: 09 July 2021 12:27
> To: Alim Akhtar <alim.akhtar@samsung.com>; James E . J . Bottomley
> <jejb@linux.ibm.com>; Martin K . Petersen <martin.petersen@oracle.com>
> Cc: Can Guo <cang@codeaurora.org>; Jaegeuk Kim <jaegeuk@kernel.org>;
> Kiwoong Kim <kwmad.kim@samsung.com>; Avri Altman
> <avri.altman@wdc.com>; Adrian Hunter <adrian.hunter@intel.com>;
> Christoph Hellwig <hch@infradead.org>; Bart Van Assche
> <bvanassche@acm.org>; jongmin jeong <jjmin.jeong@samsung.com>;
> Gyunghoon Kwon <goodjob.kwon@samsung.com>; linux-samsung-
> soc@vger.kernel.org; linux-scsi@vger.kernel.org; Chanho Park
> <chanho61.park@samsung.com>
> Subject: [PATCH 06/15] scsi: ufs: ufs-exynos: add refclkout_stop control
> 
> This patch adds REFCLKOUT_STOP control to CLK_STOP_MASK. It can
> en/disable reference clock out control for UFS device.
> 
> Signed-off-by: Chanho Park <chanho61.park@samsung.com>
> ---

Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>

>  drivers/scsi/ufs/ufs-exynos.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
> index da02ad3b036c..78cc5bda0a1f 100644
> --- a/drivers/scsi/ufs/ufs-exynos.c
> +++ b/drivers/scsi/ufs/ufs-exynos.c
> @@ -49,10 +49,11 @@
>  #define HCI_ERR_EN_T_LAYER	0x84
>  #define HCI_ERR_EN_DME_LAYER	0x88
>  #define HCI_CLKSTOP_CTRL	0xB0
> +#define REFCLKOUT_STOP		BIT(4)
>  #define REFCLK_STOP		BIT(2)
>  #define UNIPRO_MCLK_STOP	BIT(1)
>  #define UNIPRO_PCLK_STOP	BIT(0)
> -#define CLK_STOP_MASK		(REFCLK_STOP |\
> +#define CLK_STOP_MASK		(REFCLKOUT_STOP | REFCLK_STOP |\
>  				 UNIPRO_MCLK_STOP |\
>  				 UNIPRO_PCLK_STOP)
>  #define HCI_MISC		0xB4
> --
> 2.32.0
Chanho Park July 14, 2021, 3:26 a.m. UTC | #6
> > +	/*
> > +	 * This quirk needs to be enabled if the host controller cannot
> > +	 * support interface configuration.
> > +	 */
> > +	UFSHCD_QUIRK_SKIP_INTERFACE_CONFIGURATION	= 1 << 16,
> May be UFSHCD_QUIRK_SKIP_PH_CONFIGURATION

This can explain more specific meaning. I'll apply your review v2 patchset.
Thanks.

Best Regards,
Chanho Park
Rob Herring July 16, 2021, 3:03 p.m. UTC | #7
On Tue, Jul 13, 2021 at 8:58 PM Alim Akhtar <alim.akhtar@samsung.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Krzysztof Kozlowski <krzk@kernel.org>
> > Sent: 13 July 2021 16:28
> > To: Chanho Park <chanho61.park@samsung.com>
> > Cc: Alim Akhtar <alim.akhtar@samsung.com>; James E . J . Bottomley
> > <jejb@linux.ibm.com>; Martin K . Petersen <martin.petersen@oracle.com>;
> > Can Guo <cang@codeaurora.org>; Jaegeuk Kim <jaegeuk@kernel.org>;
> > Kiwoong Kim <kwmad.kim@samsung.com>; Avri Altman
> > <avri.altman@wdc.com>; Adrian Hunter <adrian.hunter@intel.com>;
> > Christoph Hellwig <hch@infradead.org>; Bart Van Assche
> > <bvanassche@acm.org>; jongmin jeong <jjmin.jeong@samsung.com>;
> > Gyunghoon Kwon <goodjob.kwon@samsung.com>; linux-samsung-
> > soc@vger.kernel.org; linux-scsi@vger.kernel.org
> > Subject: Re: [PATCH 13/15] scsi: ufs: ufs-exynos: support exynosauto v9 ufs
> > driver
> >
> > -On Fri, 9 Jul 2021 at 08:59, Chanho Park <chanho61.park@samsung.com>
> > wrote:
> > >
> > > This patch adds to support ufs variant for ExynosAuto v9 SoC. This
> > > requires control UFS IP sharability register via syscon and regmap.
> > > Regarding uic_attr, most of values can be shared with exynos7 except
> > > tx_dif_p_nsec value.
> > >
> > > Signed-off-by: Chanho Park <chanho61.park@samsung.com>
> > > ---
> > >  drivers/scsi/ufs/ufs-exynos.c | 97
> > > +++++++++++++++++++++++++++++++++++
> > >  1 file changed, 97 insertions(+)
> > >
> > > diff --git a/drivers/scsi/ufs/ufs-exynos.c
> > > b/drivers/scsi/ufs/ufs-exynos.c index 9669afe8f1f4..82f915f7a447
> > > 100644
> > > --- a/drivers/scsi/ufs/ufs-exynos.c
> > > +++ b/drivers/scsi/ufs/ufs-exynos.c
> > > @@ -15,6 +15,7 @@
> > >  #include <linux/mfd/syscon.h>
> > >  #include <linux/phy/phy.h>
> > >  #include <linux/platform_device.h>
> > > +#include <linux/regmap.h>
> > >
> > >  #include "ufshcd.h"
> > >  #include "ufshcd-pltfrm.h"
> > > @@ -76,6 +77,12 @@
> > >                                  UIC_TRANSPORT_NO_CONNECTION_RX |\
> > >                                  UIC_TRANSPORT_BAD_TC)
> > >
> > > +/* FSYS UFS Sharability */
> >
> > Sharability -> Shareability
> >
> > > +#define UFS_WR_SHARABLE                BIT(2)
> > > +#define UFS_RD_SHARABLE                BIT(1)
> > > +#define UFS_SHARABLE           (UFS_WR_SHARABLE | UFS_RD_SHARABLE)
> > > +#define UFS_SHARABILITY_OFFSET 0x710
> > > +
> > >  enum {
> > >         UNIPRO_L1_5 = 0,/* PHY Adapter */
> > >         UNIPRO_L2,      /* Data Link */
> > > @@ -151,6 +158,80 @@ static int exynos7_ufs_drv_init(struct device *dev,
> > struct exynos_ufs *ufs)
> > >         return 0;
> > >  }
> > >
> > > +static int exynosauto_ufs_drv_init(struct device *dev, struct
> > > +exynos_ufs *ufs) {
> > > +       struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
> > > +
> > > +       /* IO Coherency setting */
> > > +       if (ufs->sysreg) {
> > > +               return regmap_update_bits(ufs->sysreg,
> > UFS_SHARABILITY_OFFSET,
> > > +                                         UFS_SHARABLE, UFS_SHARABLE);
> > > +       }
> > > +
> > > +       attr->tx_dif_p_nsec = 3200000;
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static int exynosauto_ufs_pre_link(struct exynos_ufs *ufs) {
> > > +       struct ufs_hba *hba = ufs->hba;
> > > +       int i;
> > > +
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
> > > +       for_each_ufs_rx_lane(ufs, i) {
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i),
> > > +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x11, i), 0x0);
> > > +
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);
> > > +
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1b, i), 0x2);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1c, i), 0x8a);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x1d, i), 0xa3);
> > > +
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x79);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);
> > > +       }
> > > +
> > > +       for_each_ufs_tx_lane(ufs, i) {
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xaa, i),
> > > +                              DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xa9, i), 0x02);
> > > +
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xab, i), 0x8);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xac, i), 0x22);
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xad, i), 0x8);
> > > +
> > > +               ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 0x1);
> > > +       }
> > > +
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
> > > +
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE),
> > 0x0);
> > > +
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(0xa011), 0x8000);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static int exynosauto_ufs_pre_pwr_change(struct exynos_ufs *ufs,
> > > +                                        struct ufs_pa_layer_attr
> > > +*pwr) {
> > > +       struct ufs_hba *hba = ufs->hba;
> > > +
> > > +       /* PACP_PWR_req and delivered to the remote DME */
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0),
> > 12000);
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1),
> > 32000);
> > > +       ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2),
> > 16000);
> > > +
> > > +       return 0;
> > > +}
> > > +
> >
> > No need for double line.
> >
> > > +
> > >  static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)  {
> > >         struct ufs_hba *hba = ufs->hba; @@ -1305,6 +1386,20 @@ static
> > > struct exynos_ufs_uic_attr exynos7_uic_attr = {
> > >         .pa_dbg_option_suite            = 0x30103,
> > >  };
> > >
> > > +static struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
> > > +       .uic_attr               = &exynos7_uic_attr,
> > > +       .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
> > > +                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
> > > +                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
> > > +                                 UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,
> > > +       .opts                   = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
> > > +                                 EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
> > > +                                 EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
> > > +       .drv_init               = exynosauto_ufs_drv_init,
> > > +       .pre_link               = exynosauto_ufs_pre_link,
> > > +       .pre_pwr_change         = exynosauto_ufs_pre_pwr_change,
> > > +};
> > > +
> > >  static struct exynos_ufs_drv_data exynos_ufs_drvs = {
> > >         .uic_attr               = &exynos7_uic_attr,
> > >         .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
> > > @@ -1330,6 +1425,8 @@ static struct exynos_ufs_drv_data
> > > exynos_ufs_drvs = {  static const struct of_device_id
> > exynos_ufs_of_match[] = {
> > >         { .compatible = "samsung,exynos7-ufs",
> > >           .data       = &exynos_ufs_drvs },
> > > +       { .compatible = "samsung,exynosautov9-ufs",
> > > +         .data       = &exynosauto_ufs_drvs },
> >
> > This compatible is not documented. It seems that no one document
> > exynos7-ufs but that's not an excuse. :)
> >
> I was post along with UFS driver [1], had Rob's Reviewed-by as well, not sure why it is not merged.
> Let me ping Rob on this.
> [1] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2176074.html

The binding should have been applied with the driver. If you want me
to apply, resend it without my Reviewed-by tag.

Rob
Bean Huo Aug. 3, 2021, 4:57 p.m. UTC | #8
On Fri, 2021-07-09 at 15:57 +0900, Chanho Park wrote:
> We divide this M-HCI as PH(Physical Host) and VHs(Virtual Host). The
> PH
> 
> supports all UFSHCI functions(all SAPs) same as conventional UFSHCI
> but
> 
> the VH only supports data transfer function. Thus, except UTP_CMD_SAP
> and
> 
> UTP_TMPSAP, the PH should handle all the physical features.

Hi Chanho park,

You mentioned this in your coverletter:

"There are two types of host controllers on the UFS host controller
that we designed. The UFS device has a Function Arbitor that arranges
commands of each host. When each host transmits a command to the
Arbitor, the Arbitor transmits it to the UTP layer".

where does this "Function Arbitor" exit? From your comments, seems it
exists on the UFS device side? right? If this is true, where is related
code in your patch?? Maybe you only submited partial of your real
driver parch for this controller??

Bean
Chanho Park Aug. 3, 2021, 11:35 p.m. UTC | #9
> > We divide this M-HCI as PH(Physical Host) and VHs(Virtual Host). The
> > PH
> >
> > supports all UFSHCI functions(all SAPs) same as conventional UFSHCI
> > but
> >
> > the VH only supports data transfer function. Thus, except UTP_CMD_SAP
> > and
> >
> > UTP_TMPSAP, the PH should handle all the physical features.
> 
> Hi Chanho park,
> 
> You mentioned this in your coverletter:
> 
> "There are two types of host controllers on the UFS host controller that
> we designed. The UFS device has a Function Arbitor that arranges commands
> of each host. When each host transmits a command to the Arbitor, the
> Arbitor transmits it to the UTP layer".
> 
> where does this "Function Arbitor" exit? From your comments, seems it
> exists on the UFS device side? right? If this is true, where is related
> code in your patch??

The "Function Arbiter" is in our ufs controller as H/W and it is responsible to arrange UTP_CMD/UTP_TM among PH and VHs. When we set MHCTL register, the controller will enable the multi-host capability and the arbiter will be automatically enabled as well.

+static int exynosauto_ufs_post_hce_enable(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+
+	/* Enable Virtual Host #1 */
+	ufshcd_rmwl(hba, MHCTRL_EN_VH_MASK, MHCTRL_EN_VH(1), MHCTRL);
+	/* Default VH Transfer permissions */
+	hci_writel(ufs, 0x03FFE1FE, HCI_MH_ALLOWABLE_TRAN_OF_VH);
+	/* IID information is replaced in TASKTAG[7:5] instead of IID in UCD */
+	hci_writel(ufs, 0x1, HCI_MH_IID_IN_TASK_TAG);
+
+	return 0;
+}

> Maybe you only submited partial of your real driver
> parch for this controller??

Yes. The series is the initial version but it contains most of multi-host capabilities. Most of things can be handled by our UFS controller so we can make driver code simpler as much as possible. Only #1 VH can be supported in this patch at the moment but I have a plan to support more VHs later.

Best Regards,
Chanho Park