21. 10. 7. 오후 5:09에 Chanho Park 이(가) 쓴 글: > UFS controller of ExynosAuto v9 SoC supports multi-host interface for I/O > virtualization. In general, we're using para-virtualized driver to > support a block device by several virtual machines. However, it should > be relayed by backend driver. Multi-host functionality extends the host > controller by providing register interfaces that can be used by each > VM's ufs drivers respectively. By this, we can provide direct access to > the UFS device for multiple VMs. It's similar with SR-IOV of PCIe. > > 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. > > This patch provides an initial implementation of PH part. M-HCI can > support up to four interfaces but this patch initially supports only 1 > PH and 1 VH. For this, we uses TASK_TAG[7:5] field so TASK_TAG[4:0] for > 32 doorbel will be supported. After the PH is initiated, this will send > a ready message to VHs through a mailbox register. The message handler > is not fully implemented yet such as supporting reset / abort cases. > > Cc: Alim Akhtar <alim.akhtar@xxxxxxxxxxx> > Cc: Kiwoong Kim <kwmad.kim@xxxxxxxxxxx> > Cc: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxxxxx> > Cc: Inki Dae <inki.dae@xxxxxxxxxxx> > Signed-off-by: Chanho Park <chanho61.park@xxxxxxxxxxx> > --- > drivers/scsi/ufs/ufs-exynos.c | 68 +++++++++++++++++++++++++++++++++++ > 1 file changed, 68 insertions(+) > > diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c > index 9d32f19395b8..32f73c906018 100644 > --- a/drivers/scsi/ufs/ufs-exynos.c > +++ b/drivers/scsi/ufs/ufs-exynos.c > @@ -83,6 +83,44 @@ > #define UFS_SHARABLE (UFS_WR_SHARABLE | UFS_RD_SHARABLE) > #define UFS_SHAREABILITY_OFFSET 0x710 > > +/* Multi-host registers */ > +#define MHCTRL 0xC4 > +#define MHCTRL_EN_VH_MASK (0xE) > +#define MHCTRL_EN_VH(vh) (vh << 1) > +#define PH2VH_MBOX 0xD8 > + > +#define MH_MSG_MASK (0xFF) > + > +#define MH_MSG(id, msg) ((id << 8) | (msg & 0xFF)) > +#define MH_MSG_PH_READY 0x1 > +#define MH_MSG_VH_READY 0x2 > + > +#define ALLOW_INQUIRY BIT(25) > +#define ALLOW_MODE_SELECT BIT(24) > +#define ALLOW_MODE_SENSE BIT(23) > +#define ALLOW_PRE_FETCH GENMASK(22, 21) > +#define ALLOW_READ_CMD_ALL GENMASK(20, 18) /* read_6/10/16 */ > +#define ALLOW_READ_BUFFER BIT(17) > +#define ALLOW_READ_CAPACITY GENMASK(16, 15) > +#define ALLOW_REPORT_LUNS BIT(14) > +#define ALLOW_REQUEST_SENSE BIT(13) > +#define ALLOW_SYNCHRONIZE_CACHE GENMASK(8, 7) > +#define ALLOW_TEST_UNIT_READY BIT(6) > +#define ALLOW_UNMAP BIT(5) > +#define ALLOW_VERIFY BIT(4) > +#define ALLOW_WRITE_CMD_ALL GENMASK(3, 1) /* write_6/10/16 */ > + > +#define ALLOW_TRANS_VH_DEFAULT (ALLOW_INQUIRY | ALLOW_MODE_SELECT | \ > + ALLOW_MODE_SENSE | ALLOW_PRE_FETCH | \ > + ALLOW_READ_CMD_ALL | ALLOW_READ_BUFFER | \ > + ALLOW_READ_CAPACITY | ALLOW_REPORT_LUNS | \ > + ALLOW_REQUEST_SENSE | ALLOW_SYNCHRONIZE_CACHE | \ > + ALLOW_TEST_UNIT_READY | ALLOW_UNMAP | \ > + ALLOW_VERIFY | ALLOW_WRITE_CMD_ALL) > + > +#define HCI_MH_ALLOWABLE_TRAN_OF_VH 0x30C > +#define HCI_MH_IID_IN_TASK_TAG 0X308 > + > enum { > UNIPRO_L1_5 = 0,/* PHY Adapter */ > UNIPRO_L2, /* Data Link */ > @@ -174,6 +212,20 @@ static int exynosauto_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs) > return 0; > } > > +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, ALLOW_TRANS_VH_DEFAULT, 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); > + Reviewed-by : Inki Dae <inki.dae@xxxxxxxxxxx> Thanks, Inki Dae