Skip to content

Commit 57cb62a

Browse files
committed
[sdio][dm] add new SDIO/SDHCI drivers
1. SDHCI support on PCI bus 2. Synopsys DesignWare MMC Family(MMIO/PCI) Signed-off-by: GuEe-GUI <[email protected]>
1 parent b8b1191 commit 57cb62a

File tree

8 files changed

+3999
-0
lines changed

8 files changed

+3999
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,22 @@
1+
config RT_SDIO_SDHCI_PCI
2+
bool "SDHCI support on PCI bus"
3+
depends on RT_USING_PCI
4+
select RT_USING_SDHCI
5+
default n
6+
7+
config RT_SDIO_DW_MMC
8+
bool "Synopsys DesignWare MMC Family"
9+
depends on RT_USING_PINCTRL
10+
depends on RT_USING_RESET
11+
depends on RT_USING_REGULATOR
12+
select RT_USING_DEVICE_IPC
13+
select RT_USING_SYSTEM_WORKQUEUE
14+
default n
15+
16+
config RT_SDIO_DW_MMC_PCI
17+
bool "Synopsys Designware MCI support on PCI bus"
18+
depends on RT_SDIO_DW_MMC
19+
depends on RT_USING_PCI
20+
default n
21+
122
osource "$(SOC_DM_SDIO_DIR)/Kconfig"

components/drivers/sdio/host/SConscript

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ CPPPATH = [cwd + '/../../include']
1010

1111
src = []
1212

13+
if GetDepend(['RT_SDIO_SDHCI_PCI']):
14+
src += ['sdhci-pci.c']
15+
16+
if GetDepend(['RT_SDIO_DW_MMC']):
17+
src += ['sdio-dw.c', 'sdio-dw-platform.c']
18+
19+
if GetDepend(['RT_SDIO_DW_MMC_PCI']):
20+
src += ['sdio-dw-pci.c']
21+
1322
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
1423

1524
Return('group')
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright (c) 2006-2022, 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+
#define SDHCI_REG_BAR 0
12+
13+
#include "../dev_sdio_dm.h"
14+
15+
struct pci_sdhci_host
16+
{
17+
struct rt_sdhci_host parent;
18+
};
19+
20+
static const struct rt_sdhci_ops pci_sdhci_ops =
21+
{
22+
.set_clock = rt_sdhci_set_clock,
23+
.set_bus_width = rt_sdhci_set_bus_width,
24+
.reset = rt_sdhci_reset,
25+
};
26+
27+
static rt_err_t pci_sdhci_probe(struct rt_pci_device *pdev)
28+
{
29+
rt_err_t err;
30+
struct rt_sdhci_host *host;
31+
struct pci_sdhci_host *pci_host;
32+
33+
host = rt_sdhci_alloc_host(&pdev->parent, sizeof(struct pci_sdhci_host));
34+
35+
if (!host)
36+
{
37+
return -RT_ENOMEM;
38+
}
39+
pci_host = rt_container_of(host, struct pci_sdhci_host, parent);
40+
41+
host->ioaddr = rt_pci_iomap(pdev, SDHCI_REG_BAR);
42+
43+
if (!host->ioaddr)
44+
{
45+
err = -RT_EIO;
46+
goto _fail;
47+
}
48+
49+
host->irq = pdev->irq;
50+
host->ops = &pci_sdhci_ops;
51+
52+
rt_pci_irq_unmask(pdev);
53+
rt_pci_set_master(pdev);
54+
55+
if ((err = rt_sdhci_set_and_add_host(host)))
56+
{
57+
goto _fail;
58+
}
59+
60+
pdev->parent.user_data = pci_host;
61+
62+
return RT_EOK;
63+
64+
_fail:
65+
if (host->ioaddr)
66+
{
67+
rt_iounmap(host->ioaddr);
68+
}
69+
70+
rt_sdhci_free_host(host);
71+
72+
return err;
73+
}
74+
75+
static rt_err_t pci_sdhci_remove(struct rt_pci_device *pdev)
76+
{
77+
rt_bool_t dead;
78+
struct rt_sdhci_host *host;
79+
struct pci_sdhci_host *pci_host = pdev->parent.user_data;
80+
81+
host = &pci_host->parent;
82+
83+
/* INTx is shared, don't mask all */
84+
rt_hw_interrupt_umask(pdev->irq);
85+
rt_pci_irq_mask(pdev);
86+
rt_pci_clear_master(pdev);
87+
88+
dead = (HWREG32(host->ioaddr + RT_SDHCI_INT_STATUS) == 0xffffffff);
89+
90+
rt_sdhci_uninit_host(host, dead);
91+
92+
rt_iounmap(host->ioaddr);
93+
rt_sdhci_free_host(host);
94+
95+
return RT_EOK;
96+
}
97+
98+
static const struct rt_pci_device_id pci_sdhci_pci_ids[] =
99+
{
100+
{ RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0007), },
101+
{ RT_PCI_DEVICE_CLASS(PCIS_SYSTEM_SDHCI, ~0) },
102+
{ /* sentinel */ }
103+
};
104+
105+
static struct rt_pci_driver pci_sdhci_driver =
106+
{
107+
.name = "sdhci-pci",
108+
109+
.ids = pci_sdhci_pci_ids,
110+
.probe = pci_sdhci_probe,
111+
.remove = pci_sdhci_remove,
112+
};
113+
RT_PCI_DRIVER_EXPORT(pci_sdhci_driver);
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-12-06 GuEe-GUI first version
9+
*/
10+
11+
#include "dev_sdio_dw.h"
12+
13+
#include <mmu.h>
14+
15+
#define SYNOPSYS_DW_MCI_VENDOR_ID 0x0700
16+
#define SYNOPSYS_DW_MCI_DEVICE_ID 0x1107
17+
18+
#define MCI_REG_NO 2
19+
20+
static const struct sdio_dw_drv_data sdio_dw_pci_drv_data =
21+
{
22+
};
23+
24+
static rt_err_t sdio_dw_pci_probe(struct rt_pci_device *pdev)
25+
{
26+
rt_err_t err;
27+
struct sdio_dw *sd = rt_calloc(1, sizeof(*sd));
28+
29+
if (!sd)
30+
{
31+
return -RT_ENOMEM;
32+
}
33+
34+
sd->bus_dev = &pdev->parent;
35+
sd->base = rt_pci_iomap(pdev, MCI_REG_NO);
36+
37+
if (!sd->base)
38+
{
39+
goto _fail;
40+
}
41+
42+
sd->irq = pdev->irq;
43+
rt_pci_irq_unmask(pdev);
44+
45+
sd->base_phy = (rt_ubase_t)rt_kmem_v2p(sd->base);
46+
sd->drv_data = &sdio_dw_pci_drv_data;
47+
48+
/* board data */
49+
sd->bus_hz = 33 * 1000 * 1000;
50+
sd->detect_delay_ms = 200;
51+
sd->fifo_depth = 32;
52+
53+
pdev->parent.user_data = sd;
54+
55+
if ((err = sdio_dw_probe(sd)))
56+
{
57+
goto _fail;
58+
}
59+
60+
return RT_EOK;
61+
62+
_fail:
63+
if (sd->base)
64+
{
65+
rt_iounmap(sd->base);
66+
}
67+
68+
rt_free(sd);
69+
70+
return err;
71+
}
72+
73+
static rt_err_t sdio_dw_pci_remove(struct rt_pci_device *pdev)
74+
{
75+
struct sdio_dw *sd = pdev->parent.user_data;
76+
77+
sdio_dw_remove(sd);
78+
79+
rt_iounmap(sd->base);
80+
81+
rt_free(sd);
82+
83+
return RT_EOK;
84+
}
85+
86+
static const struct rt_pci_device_id sdio_dw_pci_pci_ids[] =
87+
{
88+
{ RT_PCI_DEVICE_ID(SYNOPSYS_DW_MCI_VENDOR_ID, SYNOPSYS_DW_MCI_DEVICE_ID) },
89+
{ /* sentinel */ }
90+
};
91+
92+
static struct rt_pci_driver sdio_dw_pci_driver =
93+
{
94+
.name = "dw-mmc-pci",
95+
96+
.ids = sdio_dw_pci_pci_ids,
97+
.probe = sdio_dw_pci_probe,
98+
.remove = sdio_dw_pci_remove,
99+
};
100+
RT_PCI_DRIVER_EXPORT(sdio_dw_pci_driver);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-12-06 GuEe-GUI first version
9+
*/
10+
11+
#include "sdio-dw-platform.h"
12+
13+
#include <mmu.h>
14+
15+
rt_err_t sdio_dw_platform_register(struct rt_platform_device *pdev,
16+
const struct sdio_dw_drv_data *drv_data)
17+
{
18+
rt_err_t err = RT_EOK;
19+
struct rt_device *dev = &pdev->parent;
20+
struct sdio_dw *sd = rt_calloc(1, sizeof(*sd));
21+
22+
if (!sd)
23+
{
24+
return -RT_ENOMEM;
25+
}
26+
27+
sd->bus_dev = &pdev->parent;
28+
sd->base = rt_dm_dev_iomap(dev, 0);
29+
30+
if (!sd->base)
31+
{
32+
err = -RT_EIO;
33+
goto _fail;
34+
}
35+
36+
sd->irq = rt_dm_dev_get_irq(dev, 0);
37+
38+
if (sd->irq < 0)
39+
{
40+
err = sd->irq;
41+
42+
goto _fail;
43+
}
44+
45+
sd->parent.ofw_node = dev->ofw_node;
46+
47+
sd->base_phy = (rt_ubase_t)rt_kmem_v2p(sd->base);
48+
sd->drv_data = drv_data;
49+
50+
pdev->parent.user_data = sd;
51+
52+
if ((err = sdio_dw_probe(sd)))
53+
{
54+
goto _fail;
55+
}
56+
57+
return RT_EOK;
58+
59+
_fail:
60+
if (sd->base)
61+
{
62+
rt_iounmap(sd->base);
63+
}
64+
65+
rt_free(sd);
66+
67+
return err;
68+
}
69+
70+
static rt_err_t sdio_dw_platform_probe(struct rt_platform_device *pdev)
71+
{
72+
const struct sdio_dw_drv_data *drv_data = RT_NULL;
73+
74+
if (pdev->parent.ofw_node)
75+
{
76+
drv_data = pdev->id->data;
77+
}
78+
79+
return sdio_dw_platform_register(pdev, drv_data);
80+
}
81+
82+
static rt_err_t sdio_dw_platform_remove(struct rt_platform_device *pdev)
83+
{
84+
struct sdio_dw *sd = pdev->parent.user_data;
85+
86+
sdio_dw_remove(sd);
87+
88+
rt_iounmap(sd->base);
89+
90+
rt_free(sd);
91+
92+
return RT_EOK;
93+
}
94+
95+
static const struct rt_ofw_node_id sdio_dw_platform_ofw_ids[] =
96+
{
97+
{ .compatible = "snps,dw-mshc", },
98+
{ .compatible = "img,pistachio-dw-mshc", },
99+
{ /* sentinel */ }
100+
};
101+
102+
static struct rt_platform_driver sdio_dw_platform_driver =
103+
{
104+
.name = "dw-mmc",
105+
.ids = sdio_dw_platform_ofw_ids,
106+
107+
.probe = sdio_dw_platform_probe,
108+
.remove = sdio_dw_platform_remove,
109+
};
110+
RT_PLATFORM_DRIVER_EXPORT(sdio_dw_platform_driver);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2006-2022, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2022-12-06 GuEe-GUI first version
9+
*/
10+
11+
#ifndef __SDIO_DW_PLATFORM_H__
12+
#define __SDIO_DW_PLATFORM_H__
13+
14+
#include "sdio-dw.h"
15+
16+
rt_err_t sdio_dw_platform_register(struct rt_platform_device *pdev,
17+
const struct sdio_dw_drv_data *drv_data);
18+
19+
#endif /* __SDIO_DW_PLATFORM_H__ */

0 commit comments

Comments
 (0)