Skip to content

Commit ea13820

Browse files
GuEe-GUIRbb666
authored andcommitted
[dm][ufs] support Universal Flash Storage (UFS)
Support UFS over PCI, too. Signed-off-by: GuEe-GUI <2991707448@qq.com>
1 parent c1a43bc commit ea13820

8 files changed

Lines changed: 1912 additions & 0 deletions

File tree

components/drivers/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ rsource "ata/Kconfig"
3030
rsource "nvme/Kconfig"
3131
rsource "block/Kconfig"
3232
rsource "scsi/Kconfig"
33+
rsource "ufs/Kconfig"
3334
rsource "firmware/Kconfig"
3435
rsource "hwcache/Kconfig"
3536
rsource "regulator/Kconfig"

components/drivers/include/drivers/ufs.h

Lines changed: 662 additions & 0 deletions
Large diffs are not rendered by default.

components/drivers/include/rtdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ extern "C" {
135135
#include "drivers/thermal.h"
136136
#endif /* RT_USING_THERMAL */
137137

138+
#ifdef RT_USING_UFS
139+
#include "drivers/ufs.h"
140+
#endif /* RT_USING_UFS */
141+
138142
#ifdef RT_USING_FIRMWARE
139143
#ifdef RT_FIRMWARE_ARM_SCMI
140144
#include "drivers/scmi.h"

components/drivers/ufs/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
menuconfig RT_USING_UFS
2+
bool "Using Universal Flash Storage (UFS) device drivers"
3+
depends on RT_USING_DM
4+
depends on RT_USING_DMA
5+
depends on RT_SCSI_SD
6+
default n
7+
8+
config RT_UFS_PCI
9+
bool "UFS support on PCI bus"
10+
depends on RT_USING_UFS
11+
depends on RT_USING_PCI
12+
default n
13+
14+
if RT_USING_UFS
15+
osource "$(SOC_DM_UFS_DIR)/Kconfig"
16+
endif

components/drivers/ufs/SConscript

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from building import *
2+
3+
group = []
4+
5+
if not GetDepend(['RT_USING_UFS']):
6+
Return('group')
7+
8+
cwd = GetCurrentDir()
9+
CPPPATH = [cwd + '/../include']
10+
11+
src = ['ufs.c', 'ufs_pm.c']
12+
13+
if GetDepend(['RT_UFS_PCI']):
14+
src += ['ufs-pci.c']
15+
16+
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
17+
18+
Return('group')

components/drivers/ufs/ufs-pci.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2006-2023, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2023-02-25 GuEe-GUI the first version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
14+
#define UFS_REG_BAR 0
15+
16+
struct pci_ufs_quirk
17+
{
18+
const struct rt_ufs_ops *ops;
19+
};
20+
21+
struct pci_ufs_host
22+
{
23+
struct rt_ufs_host parent;
24+
const struct pci_ufs_quirk *quirk;
25+
};
26+
27+
static const struct rt_ufs_ops pci_ufs_std_ops =
28+
{
29+
};
30+
31+
static rt_err_t pci_ufs_probe(struct rt_pci_device *pdev)
32+
{
33+
rt_err_t err;
34+
struct rt_ufs_host *ufs;
35+
struct pci_ufs_host *pci_ufs = rt_calloc(1, sizeof(*pci_ufs));
36+
const struct pci_ufs_quirk *quirk = pdev->id->data;
37+
38+
if (!pci_ufs)
39+
{
40+
return -RT_ENOMEM;
41+
}
42+
43+
pci_ufs->quirk = quirk;
44+
ufs = &pci_ufs->parent;
45+
ufs->parent.dev = &pdev->parent;
46+
ufs->regs = rt_pci_iomap(pdev, UFS_REG_BAR);
47+
ufs->irq = pdev->irq;
48+
49+
if (!ufs->regs)
50+
{
51+
err = -RT_EIO;
52+
goto _fail;
53+
}
54+
55+
ufs->ops = quirk ? quirk->ops : &pci_ufs_std_ops;
56+
57+
rt_pci_irq_unmask(pdev);
58+
rt_pci_set_master(pdev);
59+
60+
if ((err = rt_ufs_host_register(ufs)))
61+
{
62+
goto _fail;
63+
}
64+
65+
pdev->parent.user_data = pci_ufs;
66+
67+
return RT_EOK;
68+
69+
_fail:
70+
rt_free(pci_ufs);
71+
72+
return err;
73+
}
74+
75+
static rt_err_t pci_ufs_remove(struct rt_pci_device *pdev)
76+
{
77+
struct rt_ufs_host *ufs;
78+
struct pci_ufs_host *pci_ufs = pdev->parent.user_data;
79+
80+
ufs = &pci_ufs->parent;
81+
82+
rt_ufs_host_unregister(ufs);
83+
84+
/* INTx is shared, don't mask all */
85+
rt_hw_interrupt_umask(pdev->irq);
86+
rt_pci_irq_mask(pdev);
87+
rt_pci_clear_master(pdev);
88+
89+
rt_iounmap(ufs->regs);
90+
rt_free(pci_ufs);
91+
92+
return RT_EOK;
93+
}
94+
95+
static rt_err_t pci_ufs_shutdown(struct rt_pci_device *pdev)
96+
{
97+
return pci_ufs_remove(pdev);
98+
}
99+
100+
static const struct rt_pci_device_id pci_ufs_ids[] =
101+
{
102+
{ RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0013), },
103+
{ RT_PCI_DEVICE_ID(PCI_VENDOR_ID_SAMSUNG, 0xc00c), },
104+
{ /* sentinel */ }
105+
};
106+
107+
static struct rt_pci_driver pci_ufs_driver =
108+
{
109+
.name = "ufs-pci",
110+
111+
.ids = pci_ufs_ids,
112+
.probe = pci_ufs_probe,
113+
.remove = pci_ufs_remove,
114+
.shutdown = pci_ufs_shutdown,
115+
};
116+
RT_PCI_DRIVER_EXPORT(pci_ufs_driver);

0 commit comments

Comments
 (0)