Skip to content

Commit d11e0a3

Browse files
petegriffinmartinkpetersen
authored andcommitted
scsi: ufs: exynos: Add support for Tensor gs101 SoC
Add a dedicated compatible and drv_data with associated hooks for gs101 SoC found on Pixel 6. Note we make use of the previously added EXYNOS_UFS_OPT_UFSPR_SECURE option, to skip initialisation of UFSPR registers as these are only accessible via SMC call. EXYNOS_UFS_OPT_TIMER_TICK_SELECT option is also set to select tick source. This has been done so as not to effect any existing platforms. DBG_OPTION_SUITE on gs101 has different address offsets to other SoCs so these register offsets now come from uic_attr struct. Signed-off-by: Peter Griffin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Krzysztof Kozlowski <[email protected]> Tested-by: Will McVicker <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 6f9f0d5 commit d11e0a3

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

drivers/ufs/host/ufs-exynos.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#define CLK_STOP_MASK (REFCLKOUT_STOP | REFCLK_STOP |\
6262
UNIPRO_MCLK_STOP | MPHY_APBCLK_STOP|\
6363
UNIPRO_PCLK_STOP)
64+
/* HCI_MISC is also known as HCI_FORCE_HCS */
6465
#define HCI_MISC 0xB4
6566
#define REFCLK_CTRL_EN BIT(7)
6667
#define UNIPRO_PCLK_CTRL_EN BIT(6)
@@ -138,6 +139,9 @@ enum {
138139
/*
139140
* UNIPRO registers
140141
*/
142+
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0 0x7888
143+
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1 0x788c
144+
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2 0x7890
141145
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0 0x78B8
142146
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1 0x78BC
143147
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2 0x78C0
@@ -938,6 +942,10 @@ static void exynos_ufs_config_unipro(struct exynos_ufs *ufs)
938942
if (attr->pa_dbg_opt_suite1_off)
939943
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_opt_suite1_off),
940944
attr->pa_dbg_opt_suite1_val);
945+
946+
if (attr->pa_dbg_opt_suite2_off)
947+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_opt_suite2_off),
948+
attr->pa_dbg_opt_suite2_val);
941949
}
942950

943951
static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index)
@@ -1593,6 +1601,96 @@ static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
15931601
return 0;
15941602
}
15951603

1604+
static inline u32 get_mclk_period_unipro_18(struct exynos_ufs *ufs)
1605+
{
1606+
return (16 * 1000 * 1000000UL / ufs->mclk_rate);
1607+
}
1608+
1609+
static int gs101_ufs_pre_link(struct exynos_ufs *ufs)
1610+
{
1611+
struct ufs_hba *hba = ufs->hba;
1612+
int i;
1613+
u32 tx_line_reset_period, rx_line_reset_period;
1614+
1615+
rx_line_reset_period = (RX_LINE_RESET_TIME * ufs->mclk_rate)
1616+
/ NSEC_PER_MSEC;
1617+
tx_line_reset_period = (TX_LINE_RESET_TIME * ufs->mclk_rate)
1618+
/ NSEC_PER_MSEC;
1619+
1620+
unipro_writel(ufs, get_mclk_period_unipro_18(ufs), COMP_CLK_PERIOD);
1621+
1622+
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
1623+
1624+
for_each_ufs_rx_lane(ufs, i) {
1625+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_CLK_PRD, i),
1626+
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
1627+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_CLK_PRD_EN, i), 0x0);
1628+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE2, i),
1629+
(rx_line_reset_period >> 16) & 0xFF);
1630+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE1, i),
1631+
(rx_line_reset_period >> 8) & 0xFF);
1632+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE0, i),
1633+
(rx_line_reset_period) & 0xFF);
1634+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x69);
1635+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);
1636+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);
1637+
}
1638+
1639+
for_each_ufs_tx_lane(ufs, i) {
1640+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_CLK_PRD, i),
1641+
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
1642+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_CLK_PRD_EN, i),
1643+
0x02);
1644+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE2, i),
1645+
(tx_line_reset_period >> 16) & 0xFF);
1646+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE1, i),
1647+
(tx_line_reset_period >> 8) & 0xFF);
1648+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE0, i),
1649+
(tx_line_reset_period) & 0xFF);
1650+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 1);
1651+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x7F, i), 0);
1652+
}
1653+
1654+
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
1655+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
1656+
ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID), 0x0);
1657+
ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), 0x1);
1658+
ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), 0x1);
1659+
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_CONNECTED);
1660+
ufshcd_dme_set(hba, UIC_ARG_MIB(0xA006), 0x8000);
1661+
1662+
return 0;
1663+
}
1664+
1665+
static int gs101_ufs_post_link(struct exynos_ufs *ufs)
1666+
{
1667+
struct ufs_hba *hba = ufs->hba;
1668+
1669+
exynos_ufs_enable_dbg_mode(hba);
1670+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0x3e8);
1671+
exynos_ufs_disable_dbg_mode(hba);
1672+
1673+
return 0;
1674+
}
1675+
1676+
static int gs101_ufs_pre_pwr_change(struct exynos_ufs *ufs,
1677+
struct ufs_pa_layer_attr *pwr)
1678+
{
1679+
struct ufs_hba *hba = ufs->hba;
1680+
1681+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
1682+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
1683+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
1684+
unipro_writel(ufs, 8064, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0);
1685+
unipro_writel(ufs, 28224, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1);
1686+
unipro_writel(ufs, 20160, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2);
1687+
unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0);
1688+
unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1);
1689+
unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2);
1690+
1691+
return 0;
1692+
}
1693+
15961694
static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
15971695
.name = "exynos_ufs",
15981696
.init = exynos_ufs_init,
@@ -1720,6 +1818,34 @@ static const struct exynos_ufs_drv_data exynos_ufs_drvs = {
17201818
.post_pwr_change = exynos7_ufs_post_pwr_change,
17211819
};
17221820

1821+
static struct exynos_ufs_uic_attr gs101_uic_attr = {
1822+
.tx_trailingclks = 0xff,
1823+
.tx_dif_p_nsec = 3000000, /* unit: ns */
1824+
.tx_dif_n_nsec = 1000000, /* unit: ns */
1825+
.tx_high_z_cnt_nsec = 20000, /* unit: ns */
1826+
.tx_base_unit_nsec = 100000, /* unit: ns */
1827+
.tx_gran_unit_nsec = 4000, /* unit: ns */
1828+
.tx_sleep_cnt = 1000, /* unit: ns */
1829+
.tx_min_activatetime = 0xa,
1830+
.rx_filler_enable = 0x2,
1831+
.rx_dif_p_nsec = 1000000, /* unit: ns */
1832+
.rx_hibern8_wait_nsec = 4000000, /* unit: ns */
1833+
.rx_base_unit_nsec = 100000, /* unit: ns */
1834+
.rx_gran_unit_nsec = 4000, /* unit: ns */
1835+
.rx_sleep_cnt = 1280, /* unit: ns */
1836+
.rx_stall_cnt = 320, /* unit: ns */
1837+
.rx_hs_g1_sync_len_cap = SYNC_LEN_COARSE(0xf),
1838+
.rx_hs_g2_sync_len_cap = SYNC_LEN_COARSE(0xf),
1839+
.rx_hs_g3_sync_len_cap = SYNC_LEN_COARSE(0xf),
1840+
.rx_hs_g1_prep_sync_len_cap = PREP_LEN(0xf),
1841+
.rx_hs_g2_prep_sync_len_cap = PREP_LEN(0xf),
1842+
.rx_hs_g3_prep_sync_len_cap = PREP_LEN(0xf),
1843+
.pa_dbg_opt_suite1_val = 0x90913C1C,
1844+
.pa_dbg_opt_suite1_off = PA_GS101_DBG_OPTION_SUITE1,
1845+
.pa_dbg_opt_suite2_val = 0xE01C115F,
1846+
.pa_dbg_opt_suite2_off = PA_GS101_DBG_OPTION_SUITE2,
1847+
};
1848+
17231849
static struct exynos_ufs_uic_attr fsd_uic_attr = {
17241850
.tx_trailingclks = 0x10,
17251851
.tx_dif_p_nsec = 3000000, /* unit: ns */
@@ -1763,7 +1889,27 @@ static const struct exynos_ufs_drv_data fsd_ufs_drvs = {
17631889
.pre_pwr_change = fsd_ufs_pre_pwr_change,
17641890
};
17651891

1892+
static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
1893+
.uic_attr = &gs101_uic_attr,
1894+
.quirks = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
1895+
UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
1896+
UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
1897+
UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
1898+
UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL |
1899+
UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,
1900+
.opts = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
1901+
EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
1902+
EXYNOS_UFS_OPT_UFSPR_SECURE |
1903+
EXYNOS_UFS_OPT_TIMER_TICK_SELECT,
1904+
.drv_init = exynosauto_ufs_drv_init,
1905+
.pre_link = gs101_ufs_pre_link,
1906+
.post_link = gs101_ufs_post_link,
1907+
.pre_pwr_change = gs101_ufs_pre_pwr_change,
1908+
};
1909+
17661910
static const struct of_device_id exynos_ufs_of_match[] = {
1911+
{ .compatible = "google,gs101-ufs",
1912+
.data = &gs101_ufs_drvs },
17671913
{ .compatible = "samsung,exynos7-ufs",
17681914
.data = &exynos_ufs_drvs },
17691915
{ .compatible = "samsung,exynosautov9-ufs",

drivers/ufs/host/ufs-exynos.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
#ifndef _UFS_EXYNOS_H_
1010
#define _UFS_EXYNOS_H_
1111

12+
/*
13+
* Component registers
14+
*/
15+
16+
#define COMP_CLK_PERIOD 0x44
17+
1218
/*
1319
* UNIPRO registers
1420
*/
@@ -29,6 +35,14 @@
2935
#define PA_DBG_OPTION_SUITE 0x9564
3036
#define PA_DBG_OPTION_SUITE_DYN 0x9565
3137

38+
/*
39+
* Note: GS101_DBG_OPTION offsets below differ from the TRM
40+
* but match the downstream driver. Following the TRM
41+
* results in non-functioning UFS.
42+
*/
43+
#define PA_GS101_DBG_OPTION_SUITE1 0x956a
44+
#define PA_GS101_DBG_OPTION_SUITE2 0x956d
45+
3246
/*
3347
* MIBs for Transport Layer debug registers
3448
*/

0 commit comments

Comments
 (0)