Message ID | 20210709065711.25195-1-chanho61.park@samsung.com |
---|---|
Headers | show |
Series | introduce exynosauto v9 ufs driver | expand |
-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
> > +/* 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
> -----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
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
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
> > + /* > > + * 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
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
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
> > 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