[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <003501d87add$da15c310$8e414930$@samsung.com>
Date: Wed, 8 Jun 2022 11:17:07 +0900
From: "Chanho Park" <chanho61.park@...sung.com>
To: "'Alim Akhtar'" <alim.akhtar@...sung.com>,
<linux-arm-kernel@...ts.infradead.org>,
<linux-kernel@...r.kernel.org>, <linux-scsi@...r.kernel.org>,
<linux-phy@...ts.infradead.org>
Cc: <devicetree@...r.kernel.org>, <robh+dt@...nel.org>,
<krzysztof.kozlowski+dt@...aro.org>, <vkoul@...nel.org>,
<avri.altman@....com>, <bvanassche@....org>,
<martin.petersen@...cle.com>, <pankaj.dubey@...sung.com>,
"'Bharat Uppal'" <bharat.uppal@...sung.com>
Subject: RE: [PATCH v2 6/7] ufs: host: ufs-exynos: add support for fsd ufs
hci
> Subject: [PATCH v2 6/7] ufs: host: ufs-exynos: add support for fsd ufs hci
>
> Adds support of UFS HCI which is found in Tesla Full Self-Driving (FSD)
> SoC.
>
> Signed-off-by: Bharat Uppal <bharat.uppal@...sung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar@...sung.com>
> ---
> drivers/ufs/host/ufs-exynos.c | 138 ++++++++++++++++++++++++++++++++++
> 1 file changed, 138 insertions(+)
>
> diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
> index cc128aff8871..7e0ab8a8662e 100644
> --- a/drivers/ufs/host/ufs-exynos.c
> +++ b/drivers/ufs/host/ufs-exynos.c
> @@ -1474,6 +1474,102 @@ static int exynosauto_ufs_vh_init(struct ufs_hba
> *hba)
> return 0;
> }
>
> +static int fsd_ufs_pre_link(struct exynos_ufs *ufs) {
> + int i;
> + struct ufs_hba *hba = ufs->hba;
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x9514), 1000000000L / ufs-
> >mclk_rate);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x201), 0x12);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
> +
> + for_each_ufs_tx_lane(ufs, i) {
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xAA, i), 1000000000L /
> ufs->mclk_rate);
Use NSEC_PER_SEC and DIV_ROUND_UP as well.
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8F, i), 0x3F);
> + }
> +
> + for_each_ufs_rx_lane(ufs, i) {
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i), 1000000000L /
> ufs->mclk_rate);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x5C, i), 0x38);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0F, i), 0x0);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x65, i), 0x1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x69, i), 0x1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x21, i), 0x0);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x22, i), 0x0);
> + }
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x9536), 0x4E20);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x9564), 0x2e820183);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
> +
> + exynos_ufs_establish_connt(ufs);
> +
> + return 0;
> +}
> +
> +static int fsd_ufs_post_link(struct exynos_ufs *ufs) {
> + int i;
> + struct ufs_hba *hba = ufs->hba;
> + u32 hw_cap_min_tactivate;
> + u32 peer_rx_min_actv_time_cap;
> + u32 max_rx_hibern8_time_cap;
> +
> + ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(0x8F, 4),
> + &hw_cap_min_tactivate); /* HW Capability of
> MIN_TACTIVATE */
> + ufshcd_dme_get(hba, UIC_ARG_MIB(0x15A8),
> + &peer_rx_min_actv_time_cap); /* PA_TActivate */
> + ufshcd_dme_get(hba, UIC_ARG_MIB(0x15A7),
> + &max_rx_hibern8_time_cap); /* PA_Hibern8Time */
> +
> + if (peer_rx_min_actv_time_cap >= hw_cap_min_tactivate)
> + ufshcd_dme_peer_set(hba, UIC_ARG_MIB(0x15A8),
> + peer_rx_min_actv_time_cap + 1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x15A7), max_rx_hibern8_time_cap +
> 1);
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x9529), 0x01);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x15A4), 0xFA);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x9529), 0x00);
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
> +
> + for_each_ufs_rx_lane(ufs, i) {
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x35, i), 0x05);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x73, i), 0x01);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x41, i), 0x02);
> + ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x42, i), 0xAC);
> + }
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
> +
> + return 0;
> +}
> +
> +static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
> + struct ufs_pa_layer_attr *pwr)
> +{
> + struct ufs_hba *hba = ufs->hba;
> +
> + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), 0x1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), 0x1);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(DL_FC0PROTTIMEOUTVAL), 8064);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(DL_TC0REPLAYTIMEOUTVAL), 28224);
> + ufshcd_dme_set(hba, UIC_ARG_MIB(DL_AFC0REQTIMEOUTVAL), 20160);
> + 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);
If you set custom pwrmode setting, you'll need to set UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING.
> +
> + unipro_writel(ufs, 8064, 0x7888);
> + unipro_writel(ufs, 28224, 0x788C);
> + unipro_writel(ufs, 20160, 0x7890);
Duplicated setting with above dme_set calls. (DL_FC0PROTTIMEOUTVAL / DL_TC0REPLAYTIMEOUTVAL / DL_AFC0REQTIMEOUTVAL)
Unipro registers are mirrored and you can use unipro_* APIs but need to choose one of them.
> + unipro_writel(ufs, 12000, 0x78B8);
> + unipro_writel(ufs, 32000, 0x78BC);
> + unipro_writel(ufs, 16000, 0x78C0);
Put some documents the register as DME_POWERMODE_REQ_REMOTEL2TIMER0/1/2 or use macro for them.
Best Regards,
Chanho Park
Powered by blists - more mailing lists