Skip to content

Commit 0d9a1ec

Browse files
Merge patch series "ufs-exynos support for Tensor GS101"
Peter Griffin <[email protected]> says: Hi Martin, James & Alim, This series adds support to the ufs-exynos driver for Tensor gs101 found in Pixel 6. It was send previously in [1] and [2] but included the other clock, phy and DTS parts. This series has been split into just the ufs-exynos part to hopefully make things easier. With this series, plus the phy, clock and dts changes UFS is functional upstream for Pixel 6. The SKhynix HN8T05BZGKX015 can be enumerated, partitions mounted etc. The series is split into some prepatory patches for ufs-exynos and a final patch that adds the gs101 support. Note the sysreg clock has been moved to ufs node as fine grained clock control around the syscon sysreg register accesses doesn't result in functional UFS. regards, Peter Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
2 parents 998d09c + d11e0a3 commit 0d9a1ec

File tree

3 files changed

+240
-18
lines changed

3 files changed

+240
-18
lines changed

Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ maintainers:
1212
description: |
1313
Each Samsung UFS host controller instance should have its own node.
1414
15-
allOf:
16-
- $ref: ufs-common.yaml
17-
1815
properties:
1916
compatible:
2017
enum:
18+
- google,gs101-ufs
2119
- samsung,exynos7-ufs
2220
- samsung,exynosautov9-ufs
2321
- samsung,exynosautov9-ufs-vh
@@ -38,14 +36,24 @@ properties:
3836
- const: ufsp
3937

4038
clocks:
39+
minItems: 2
4140
items:
4241
- description: ufs link core clock
4342
- description: unipro main clock
43+
- description: fmp clock
44+
- description: ufs aclk clock
45+
- description: ufs pclk clock
46+
- description: sysreg clock
4447

4548
clock-names:
49+
minItems: 2
4650
items:
4751
- const: core_clk
4852
- const: sclk_unipro_main
53+
- const: fmp
54+
- const: aclk
55+
- const: pclk
56+
- const: sysreg
4957

5058
phys:
5159
maxItems: 1
@@ -72,6 +80,30 @@ required:
7280
- clocks
7381
- clock-names
7482

83+
allOf:
84+
- $ref: ufs-common.yaml
85+
- if:
86+
properties:
87+
compatible:
88+
contains:
89+
const: google,gs101-ufs
90+
91+
then:
92+
properties:
93+
clocks:
94+
minItems: 6
95+
96+
clock-names:
97+
minItems: 6
98+
99+
else:
100+
properties:
101+
clocks:
102+
maxItems: 2
103+
104+
clock-names:
105+
maxItems: 2
106+
75107
unevaluatedProperties: false
76108

77109
examples:

drivers/ufs/host/ufs-exynos.c

Lines changed: 183 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
#define HCI_ERR_EN_N_LAYER 0x80
5151
#define HCI_ERR_EN_T_LAYER 0x84
5252
#define HCI_ERR_EN_DME_LAYER 0x88
53+
#define HCI_V2P1_CTRL 0x8C
54+
#define IA_TICK_SEL BIT(16)
5355
#define HCI_CLKSTOP_CTRL 0xB0
5456
#define REFCLKOUT_STOP BIT(4)
5557
#define MPHY_APBCLK_STOP BIT(3)
@@ -59,6 +61,7 @@
5961
#define CLK_STOP_MASK (REFCLKOUT_STOP | REFCLK_STOP |\
6062
UNIPRO_MCLK_STOP | MPHY_APBCLK_STOP|\
6163
UNIPRO_PCLK_STOP)
64+
/* HCI_MISC is also known as HCI_FORCE_HCS */
6265
#define HCI_MISC 0xB4
6366
#define REFCLK_CTRL_EN BIT(7)
6467
#define UNIPRO_PCLK_CTRL_EN BIT(6)
@@ -136,6 +139,9 @@ enum {
136139
/*
137140
* UNIPRO registers
138141
*/
142+
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0 0x7888
143+
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1 0x788c
144+
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2 0x7890
139145
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0 0x78B8
140146
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1 0x78BC
141147
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2 0x78C0
@@ -306,8 +312,9 @@ static int exynosauto_ufs_post_pwr_change(struct exynos_ufs *ufs,
306312

307313
static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
308314
{
315+
struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
316+
u32 val = attr->pa_dbg_opt_suite1_val;
309317
struct ufs_hba *hba = ufs->hba;
310-
u32 val = ufs->drv_data->uic_attr->pa_dbg_option_suite;
311318
int i;
312319

313320
exynos_ufs_enable_ov_tm(hba);
@@ -324,12 +331,13 @@ static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
324331
UIC_ARG_MIB_SEL(TX_HIBERN8_CONTROL, i), 0x0);
325332
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_TXPHY_CFGUPDT), 0x1);
326333
udelay(1);
327-
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val | (1 << 12));
334+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_opt_suite1_off),
335+
val | (1 << 12));
328336
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_RESET_PHY), 0x1);
329337
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_LINE_RESET), 0x1);
330338
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_LINE_RESET_REQ), 0x1);
331339
udelay(1600);
332-
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val);
340+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_opt_suite1_off), val);
333341

334342
return 0;
335343
}
@@ -921,14 +929,23 @@ static int exynos_ufs_phy_init(struct exynos_ufs *ufs)
921929

922930
static void exynos_ufs_config_unipro(struct exynos_ufs *ufs)
923931
{
932+
struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
924933
struct ufs_hba *hba = ufs->hba;
925934

926-
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD),
927-
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
935+
if (attr->pa_dbg_clk_period_off)
936+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_clk_period_off),
937+
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
938+
928939
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTRAILINGCLOCKS),
929940
ufs->drv_data->uic_attr->tx_trailingclks);
930-
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE),
931-
ufs->drv_data->uic_attr->pa_dbg_option_suite);
941+
942+
if (attr->pa_dbg_opt_suite1_off)
943+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_opt_suite1_off),
944+
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);
932949
}
933950

934951
static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index)
@@ -1005,6 +1022,13 @@ static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs)
10051022
{
10061023
u32 val;
10071024

1025+
/* Select function clock (mclk) for timer tick */
1026+
if (ufs->opts & EXYNOS_UFS_OPT_TIMER_TICK_SELECT) {
1027+
val = hci_readl(ufs, HCI_V2P1_CTRL);
1028+
val |= IA_TICK_SEL;
1029+
hci_writel(ufs, val, HCI_V2P1_CTRL);
1030+
}
1031+
10081032
val = exynos_ufs_calc_time_cntr(ufs, IATOVAL_NSEC / CNTR_DIV_VAL);
10091033
hci_writel(ufs, val & CNT_VAL_1US_MASK, HCI_1US_TO_CNT_VAL);
10101034
}
@@ -1186,7 +1210,8 @@ static int exynos_ufs_init(struct ufs_hba *hba)
11861210
if (ret)
11871211
goto out;
11881212
exynos_ufs_specify_phy_time_attr(ufs);
1189-
exynos_ufs_config_smu(ufs);
1213+
if (!(ufs->opts & EXYNOS_UFS_OPT_UFSPR_SECURE))
1214+
exynos_ufs_config_smu(ufs);
11901215

11911216
hba->host->dma_alignment = SZ_4K - 1;
11921217
return 0;
@@ -1477,10 +1502,11 @@ static int exynosauto_ufs_vh_init(struct ufs_hba *hba)
14771502

14781503
static int fsd_ufs_pre_link(struct exynos_ufs *ufs)
14791504
{
1480-
int i;
1505+
struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
14811506
struct ufs_hba *hba = ufs->hba;
1507+
int i;
14821508

1483-
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD),
1509+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_clk_period_off),
14841510
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
14851511
ufshcd_dme_set(hba, UIC_ARG_MIB(0x201), 0x12);
14861512
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
@@ -1504,7 +1530,9 @@ static int fsd_ufs_pre_link(struct exynos_ufs *ufs)
15041530

15051531
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
15061532
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_AUTOMODE_THLD), 0x4E20);
1507-
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), 0x2e820183);
1533+
1534+
ufshcd_dme_set(hba, UIC_ARG_MIB(attr->pa_dbg_opt_suite1_off),
1535+
0x2e820183);
15081536
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
15091537

15101538
exynos_ufs_establish_connt(ufs);
@@ -1568,6 +1596,96 @@ static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
15681596
return 0;
15691597
}
15701598

1599+
static inline u32 get_mclk_period_unipro_18(struct exynos_ufs *ufs)
1600+
{
1601+
return (16 * 1000 * 1000000UL / ufs->mclk_rate);
1602+
}
1603+
1604+
static int gs101_ufs_pre_link(struct exynos_ufs *ufs)
1605+
{
1606+
struct ufs_hba *hba = ufs->hba;
1607+
int i;
1608+
u32 tx_line_reset_period, rx_line_reset_period;
1609+
1610+
rx_line_reset_period = (RX_LINE_RESET_TIME * ufs->mclk_rate)
1611+
/ NSEC_PER_MSEC;
1612+
tx_line_reset_period = (TX_LINE_RESET_TIME * ufs->mclk_rate)
1613+
/ NSEC_PER_MSEC;
1614+
1615+
unipro_writel(ufs, get_mclk_period_unipro_18(ufs), COMP_CLK_PERIOD);
1616+
1617+
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
1618+
1619+
for_each_ufs_rx_lane(ufs, i) {
1620+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_CLK_PRD, i),
1621+
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
1622+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_CLK_PRD_EN, i), 0x0);
1623+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE2, i),
1624+
(rx_line_reset_period >> 16) & 0xFF);
1625+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE1, i),
1626+
(rx_line_reset_period >> 8) & 0xFF);
1627+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_RX_LINERESET_VALUE0, i),
1628+
(rx_line_reset_period) & 0xFF);
1629+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x2f, i), 0x69);
1630+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x84, i), 0x1);
1631+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x25, i), 0xf6);
1632+
}
1633+
1634+
for_each_ufs_tx_lane(ufs, i) {
1635+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_CLK_PRD, i),
1636+
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
1637+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_CLK_PRD_EN, i),
1638+
0x02);
1639+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE2, i),
1640+
(tx_line_reset_period >> 16) & 0xFF);
1641+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE1, i),
1642+
(tx_line_reset_period >> 8) & 0xFF);
1643+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(VND_TX_LINERESET_PVALUE0, i),
1644+
(tx_line_reset_period) & 0xFF);
1645+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x04, i), 1);
1646+
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x7F, i), 0);
1647+
}
1648+
1649+
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
1650+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
1651+
ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID), 0x0);
1652+
ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), 0x1);
1653+
ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), 0x1);
1654+
ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_CONNECTED);
1655+
ufshcd_dme_set(hba, UIC_ARG_MIB(0xA006), 0x8000);
1656+
1657+
return 0;
1658+
}
1659+
1660+
static int gs101_ufs_post_link(struct exynos_ufs *ufs)
1661+
{
1662+
struct ufs_hba *hba = ufs->hba;
1663+
1664+
exynos_ufs_enable_dbg_mode(hba);
1665+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0x3e8);
1666+
exynos_ufs_disable_dbg_mode(hba);
1667+
1668+
return 0;
1669+
}
1670+
1671+
static int gs101_ufs_pre_pwr_change(struct exynos_ufs *ufs,
1672+
struct ufs_pa_layer_attr *pwr)
1673+
{
1674+
struct ufs_hba *hba = ufs->hba;
1675+
1676+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
1677+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
1678+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
1679+
unipro_writel(ufs, 8064, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0);
1680+
unipro_writel(ufs, 28224, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1);
1681+
unipro_writel(ufs, 20160, UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2);
1682+
unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0);
1683+
unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1);
1684+
unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2);
1685+
1686+
return 0;
1687+
}
1688+
15711689
static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
15721690
.name = "exynos_ufs",
15731691
.init = exynos_ufs_init,
@@ -1640,7 +1758,9 @@ static struct exynos_ufs_uic_attr exynos7_uic_attr = {
16401758
.rx_hs_g1_prep_sync_len_cap = PREP_LEN(0xf),
16411759
.rx_hs_g2_prep_sync_len_cap = PREP_LEN(0xf),
16421760
.rx_hs_g3_prep_sync_len_cap = PREP_LEN(0xf),
1643-
.pa_dbg_option_suite = 0x30103,
1761+
.pa_dbg_clk_period_off = PA_DBG_CLK_PERIOD,
1762+
.pa_dbg_opt_suite1_val = 0x30103,
1763+
.pa_dbg_opt_suite1_off = PA_DBG_OPTION_SUITE,
16441764
};
16451765

16461766
static const struct exynos_ufs_drv_data exynosauto_ufs_drvs = {
@@ -1692,6 +1812,34 @@ static const struct exynos_ufs_drv_data exynos_ufs_drvs = {
16921812
.post_pwr_change = exynos7_ufs_post_pwr_change,
16931813
};
16941814

1815+
static struct exynos_ufs_uic_attr gs101_uic_attr = {
1816+
.tx_trailingclks = 0xff,
1817+
.tx_dif_p_nsec = 3000000, /* unit: ns */
1818+
.tx_dif_n_nsec = 1000000, /* unit: ns */
1819+
.tx_high_z_cnt_nsec = 20000, /* unit: ns */
1820+
.tx_base_unit_nsec = 100000, /* unit: ns */
1821+
.tx_gran_unit_nsec = 4000, /* unit: ns */
1822+
.tx_sleep_cnt = 1000, /* unit: ns */
1823+
.tx_min_activatetime = 0xa,
1824+
.rx_filler_enable = 0x2,
1825+
.rx_dif_p_nsec = 1000000, /* unit: ns */
1826+
.rx_hibern8_wait_nsec = 4000000, /* unit: ns */
1827+
.rx_base_unit_nsec = 100000, /* unit: ns */
1828+
.rx_gran_unit_nsec = 4000, /* unit: ns */
1829+
.rx_sleep_cnt = 1280, /* unit: ns */
1830+
.rx_stall_cnt = 320, /* unit: ns */
1831+
.rx_hs_g1_sync_len_cap = SYNC_LEN_COARSE(0xf),
1832+
.rx_hs_g2_sync_len_cap = SYNC_LEN_COARSE(0xf),
1833+
.rx_hs_g3_sync_len_cap = SYNC_LEN_COARSE(0xf),
1834+
.rx_hs_g1_prep_sync_len_cap = PREP_LEN(0xf),
1835+
.rx_hs_g2_prep_sync_len_cap = PREP_LEN(0xf),
1836+
.rx_hs_g3_prep_sync_len_cap = PREP_LEN(0xf),
1837+
.pa_dbg_opt_suite1_val = 0x90913C1C,
1838+
.pa_dbg_opt_suite1_off = PA_GS101_DBG_OPTION_SUITE1,
1839+
.pa_dbg_opt_suite2_val = 0xE01C115F,
1840+
.pa_dbg_opt_suite2_off = PA_GS101_DBG_OPTION_SUITE2,
1841+
};
1842+
16951843
static struct exynos_ufs_uic_attr fsd_uic_attr = {
16961844
.tx_trailingclks = 0x10,
16971845
.tx_dif_p_nsec = 3000000, /* unit: ns */
@@ -1714,7 +1862,9 @@ static struct exynos_ufs_uic_attr fsd_uic_attr = {
17141862
.rx_hs_g1_prep_sync_len_cap = PREP_LEN(0xf),
17151863
.rx_hs_g2_prep_sync_len_cap = PREP_LEN(0xf),
17161864
.rx_hs_g3_prep_sync_len_cap = PREP_LEN(0xf),
1717-
.pa_dbg_option_suite = 0x2E820183,
1865+
.pa_dbg_clk_period_off = PA_DBG_CLK_PERIOD,
1866+
.pa_dbg_opt_suite1_val = 0x2E820183,
1867+
.pa_dbg_opt_suite1_off = PA_DBG_OPTION_SUITE,
17181868
};
17191869

17201870
static const struct exynos_ufs_drv_data fsd_ufs_drvs = {
@@ -1733,7 +1883,27 @@ static const struct exynos_ufs_drv_data fsd_ufs_drvs = {
17331883
.pre_pwr_change = fsd_ufs_pre_pwr_change,
17341884
};
17351885

1886+
static const struct exynos_ufs_drv_data gs101_ufs_drvs = {
1887+
.uic_attr = &gs101_uic_attr,
1888+
.quirks = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
1889+
UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
1890+
UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
1891+
UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
1892+
UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL |
1893+
UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING,
1894+
.opts = EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
1895+
EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
1896+
EXYNOS_UFS_OPT_UFSPR_SECURE |
1897+
EXYNOS_UFS_OPT_TIMER_TICK_SELECT,
1898+
.drv_init = exynosauto_ufs_drv_init,
1899+
.pre_link = gs101_ufs_pre_link,
1900+
.post_link = gs101_ufs_post_link,
1901+
.pre_pwr_change = gs101_ufs_pre_pwr_change,
1902+
};
1903+
17361904
static const struct of_device_id exynos_ufs_of_match[] = {
1905+
{ .compatible = "google,gs101-ufs",
1906+
.data = &gs101_ufs_drvs },
17371907
{ .compatible = "samsung,exynos7-ufs",
17381908
.data = &exynos_ufs_drvs },
17391909
{ .compatible = "samsung,exynosautov9-ufs",

0 commit comments

Comments
 (0)