1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates.
4 * Synopsys DesignWare xData driver
6 * Author: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
9 #include <linux/miscdevice.h>
10 #include <linux/bitfield.h>
11 #include <linux/pci-epf.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/device.h>
15 #include <linux/bitops.h>
16 #include <linux/mutex.h>
17 #include <linux/delay.h>
18 #include <linux/pci.h>
20 #define DW_XDATA_DRIVER_NAME "dw-xdata-pcie"
22 #define DW_XDATA_EP_MEM_OFFSET 0x8000000
24 static DEFINE_IDA(xdata_ida
);
26 #define STATUS_DONE BIT(0)
28 #define CONTROL_DOORBELL BIT(0)
29 #define CONTROL_IS_WRITE BIT(1)
30 #define CONTROL_LENGTH(a) FIELD_PREP(GENMASK(13, 2), a)
31 #define CONTROL_PATTERN_INC BIT(16)
32 #define CONTROL_NO_ADDR_INC BIT(18)
34 #define XPERF_CONTROL_ENABLE BIT(5)
36 #define BURST_REPEAT BIT(31)
37 #define BURST_VALUE 0x1001
39 #define PATTERN_VALUE 0x0
41 struct dw_xdata_regs
{
42 u32 addr_lsb
; /* 0x000 */
43 u32 addr_msb
; /* 0x004 */
44 u32 burst_cnt
; /* 0x008 */
45 u32 control
; /* 0x00c */
46 u32 pattern
; /* 0x010 */
47 u32 status
; /* 0x014 */
48 u32 RAM_addr
; /* 0x018 */
49 u32 RAM_port
; /* 0x01c */
50 u32 _reserved0
[14]; /* 0x020..0x054 */
51 u32 perf_control
; /* 0x058 */
52 u32 _reserved1
[41]; /* 0x05c..0x0fc */
53 u32 wr_cnt_lsb
; /* 0x100 */
54 u32 wr_cnt_msb
; /* 0x104 */
55 u32 rd_cnt_lsb
; /* 0x108 */
56 u32 rd_cnt_msb
; /* 0x10c */
59 struct dw_xdata_region
{
60 phys_addr_t paddr
; /* physical address */
61 void __iomem
*vaddr
; /* virtual address */
65 struct dw_xdata_region rg_region
; /* registers */
66 size_t max_wr_len
; /* max wr xfer len */
67 size_t max_rd_len
; /* max rd xfer len */
70 struct miscdevice misc_dev
;
73 static inline struct dw_xdata_regs __iomem
*__dw_regs(struct dw_xdata
*dw
)
75 return dw
->rg_region
.vaddr
;
78 static void dw_xdata_stop(struct dw_xdata
*dw
)
82 mutex_lock(&dw
->mutex
);
84 burst
= readl(&(__dw_regs(dw
)->burst_cnt
));
86 if (burst
& BURST_REPEAT
) {
87 burst
&= ~(u32
)BURST_REPEAT
;
88 writel(burst
, &(__dw_regs(dw
)->burst_cnt
));
91 mutex_unlock(&dw
->mutex
);
94 static void dw_xdata_start(struct dw_xdata
*dw
, bool write
)
96 struct device
*dev
= &dw
->pdev
->dev
;
99 /* Stop first if xfer in progress */
102 mutex_lock(&dw
->mutex
);
104 /* Clear status register */
105 writel(0x0, &(__dw_regs(dw
)->status
));
107 /* Burst count register set for continuous until stopped */
108 writel(BURST_REPEAT
| BURST_VALUE
, &(__dw_regs(dw
)->burst_cnt
));
110 /* Pattern register */
111 writel(PATTERN_VALUE
, &(__dw_regs(dw
)->pattern
));
113 /* Control register */
114 control
= CONTROL_DOORBELL
| CONTROL_PATTERN_INC
| CONTROL_NO_ADDR_INC
;
116 control
|= CONTROL_IS_WRITE
;
117 control
|= CONTROL_LENGTH(dw
->max_wr_len
);
119 control
|= CONTROL_LENGTH(dw
->max_rd_len
);
121 writel(control
, &(__dw_regs(dw
)->control
));
124 * The xData HW block needs about 100 ms to initiate the traffic
125 * generation according this HW block datasheet.
127 usleep_range(100, 150);
129 status
= readl(&(__dw_regs(dw
)->status
));
131 mutex_unlock(&dw
->mutex
);
133 if (!(status
& STATUS_DONE
))
134 dev_dbg(dev
, "xData: started %s direction\n",
135 write
? "write" : "read");
138 static void dw_xdata_perf_meas(struct dw_xdata
*dw
, u64
*data
, bool write
)
141 *data
= readl(&(__dw_regs(dw
)->wr_cnt_msb
));
143 *data
|= readl(&(__dw_regs(dw
)->wr_cnt_lsb
));
145 *data
= readl(&(__dw_regs(dw
)->rd_cnt_msb
));
147 *data
|= readl(&(__dw_regs(dw
)->rd_cnt_lsb
));
151 static u64
dw_xdata_perf_diff(u64
*m1
, u64
*m2
, u64 time
)
153 u64 rate
= (*m1
- *m2
);
155 rate
*= (1000 * 1000 * 1000);
157 rate
= DIV_ROUND_CLOSEST_ULL(rate
, time
);
162 static void dw_xdata_perf(struct dw_xdata
*dw
, u64
*rate
, bool write
)
164 struct device
*dev
= &dw
->pdev
->dev
;
165 u64 data
[2], time
[2], diff
;
167 mutex_lock(&dw
->mutex
);
169 /* First acquisition of current count frames */
170 writel(0x0, &(__dw_regs(dw
)->perf_control
));
171 dw_xdata_perf_meas(dw
, &data
[0], write
);
173 writel((u32
)XPERF_CONTROL_ENABLE
, &(__dw_regs(dw
)->perf_control
));
176 * Wait 100ms between the 1st count frame acquisition and the 2nd
177 * count frame acquisition, in order to calculate the speed later
181 /* Second acquisition of current count frames */
182 writel(0x0, &(__dw_regs(dw
)->perf_control
));
183 dw_xdata_perf_meas(dw
, &data
[1], write
);
185 writel((u32
)XPERF_CONTROL_ENABLE
, &(__dw_regs(dw
)->perf_control
));
190 * rate = (2nd count frames - 1st count frames) / (time elapsed)
192 diff
= jiffies_to_nsecs(time
[1] - time
[0]);
193 *rate
= dw_xdata_perf_diff(&data
[1], &data
[0], diff
);
195 mutex_unlock(&dw
->mutex
);
197 dev_dbg(dev
, "xData: time=%llu us, %s=%llu MB/s\n",
198 diff
, write
? "write" : "read", *rate
);
201 static struct dw_xdata
*misc_dev_to_dw(struct miscdevice
*misc_dev
)
203 return container_of(misc_dev
, struct dw_xdata
, misc_dev
);
206 static ssize_t
write_show(struct device
*dev
, struct device_attribute
*attr
,
209 struct miscdevice
*misc_dev
= dev_get_drvdata(dev
);
210 struct dw_xdata
*dw
= misc_dev_to_dw(misc_dev
);
213 dw_xdata_perf(dw
, &rate
, true);
215 return sysfs_emit(buf
, "%llu\n", rate
);
218 static ssize_t
write_store(struct device
*dev
, struct device_attribute
*attr
,
219 const char *buf
, size_t size
)
221 struct miscdevice
*misc_dev
= dev_get_drvdata(dev
);
222 struct dw_xdata
*dw
= misc_dev_to_dw(misc_dev
);
226 ret
= kstrtobool(buf
, &enabled
);
231 dev_dbg(dev
, "xData: requested write transfer\n");
232 dw_xdata_start(dw
, true);
234 dev_dbg(dev
, "xData: requested stop transfer\n");
241 static DEVICE_ATTR_RW(write
);
243 static ssize_t
read_show(struct device
*dev
, struct device_attribute
*attr
,
246 struct miscdevice
*misc_dev
= dev_get_drvdata(dev
);
247 struct dw_xdata
*dw
= misc_dev_to_dw(misc_dev
);
250 dw_xdata_perf(dw
, &rate
, false);
252 return sysfs_emit(buf
, "%llu\n", rate
);
255 static ssize_t
read_store(struct device
*dev
, struct device_attribute
*attr
,
256 const char *buf
, size_t size
)
258 struct miscdevice
*misc_dev
= dev_get_drvdata(dev
);
259 struct dw_xdata
*dw
= misc_dev_to_dw(misc_dev
);
263 ret
= kstrtobool(buf
, &enabled
);
268 dev_dbg(dev
, "xData: requested read transfer\n");
269 dw_xdata_start(dw
, false);
271 dev_dbg(dev
, "xData: requested stop transfer\n");
278 static DEVICE_ATTR_RW(read
);
280 static struct attribute
*xdata_attrs
[] = {
281 &dev_attr_write
.attr
,
286 ATTRIBUTE_GROUPS(xdata
);
288 static int dw_xdata_pcie_probe(struct pci_dev
*pdev
,
289 const struct pci_device_id
*pid
)
291 struct device
*dev
= &pdev
->dev
;
298 /* Enable PCI device */
299 err
= pcim_enable_device(pdev
);
301 dev_err(dev
, "enabling device failed\n");
305 /* Mapping PCI BAR regions */
306 err
= pcim_iomap_regions(pdev
, BIT(BAR_0
), pci_name(pdev
));
308 dev_err(dev
, "xData BAR I/O remapping failed\n");
312 pci_set_master(pdev
);
314 /* Allocate memory */
315 dw
= devm_kzalloc(dev
, sizeof(*dw
), GFP_KERNEL
);
319 /* Data structure initialization */
320 mutex_init(&dw
->mutex
);
322 dw
->rg_region
.vaddr
= pcim_iomap_table(pdev
)[BAR_0
];
323 if (!dw
->rg_region
.vaddr
)
326 dw
->rg_region
.paddr
= pdev
->resource
[BAR_0
].start
;
328 dw
->max_wr_len
= pcie_get_mps(pdev
);
329 dw
->max_wr_len
>>= 2;
331 dw
->max_rd_len
= pcie_get_readrq(pdev
);
332 dw
->max_rd_len
>>= 2;
336 id
= ida_alloc(&xdata_ida
, GFP_KERNEL
);
338 dev_err(dev
, "xData: unable to get id\n");
342 snprintf(name
, sizeof(name
), DW_XDATA_DRIVER_NAME
".%d", id
);
343 dw
->misc_dev
.name
= kstrdup(name
, GFP_KERNEL
);
344 if (!dw
->misc_dev
.name
) {
349 dw
->misc_dev
.minor
= MISC_DYNAMIC_MINOR
;
350 dw
->misc_dev
.parent
= dev
;
351 dw
->misc_dev
.groups
= xdata_groups
;
353 writel(0x0, &(__dw_regs(dw
)->RAM_addr
));
354 writel(0x0, &(__dw_regs(dw
)->RAM_port
));
356 addr
= dw
->rg_region
.paddr
+ DW_XDATA_EP_MEM_OFFSET
;
357 writel(lower_32_bits(addr
), &(__dw_regs(dw
)->addr_lsb
));
358 writel(upper_32_bits(addr
), &(__dw_regs(dw
)->addr_msb
));
359 dev_dbg(dev
, "xData: target address = 0x%.16llx\n", addr
);
361 dev_dbg(dev
, "xData: wr_len = %zu, rd_len = %zu\n",
362 dw
->max_wr_len
* 4, dw
->max_rd_len
* 4);
364 /* Saving data structure reference */
365 pci_set_drvdata(pdev
, dw
);
367 /* Register misc device */
368 err
= misc_register(&dw
->misc_dev
);
370 dev_err(dev
, "xData: failed to register device\n");
377 kfree(dw
->misc_dev
.name
);
380 ida_free(&xdata_ida
, id
);
385 static void dw_xdata_pcie_remove(struct pci_dev
*pdev
)
387 struct dw_xdata
*dw
= pci_get_drvdata(pdev
);
390 if (sscanf(dw
->misc_dev
.name
, DW_XDATA_DRIVER_NAME
".%d", &id
) != 1)
397 misc_deregister(&dw
->misc_dev
);
398 kfree(dw
->misc_dev
.name
);
399 ida_free(&xdata_ida
, id
);
402 static const struct pci_device_id dw_xdata_pcie_id_table
[] = {
403 { PCI_DEVICE_DATA(SYNOPSYS
, EDDA
, NULL
) },
406 MODULE_DEVICE_TABLE(pci
, dw_xdata_pcie_id_table
);
408 static struct pci_driver dw_xdata_pcie_driver
= {
409 .name
= DW_XDATA_DRIVER_NAME
,
410 .id_table
= dw_xdata_pcie_id_table
,
411 .probe
= dw_xdata_pcie_probe
,
412 .remove
= dw_xdata_pcie_remove
,
415 module_pci_driver(dw_xdata_pcie_driver
);
417 MODULE_LICENSE("GPL v2");
418 MODULE_DESCRIPTION("Synopsys DesignWare xData PCIe driver");
419 MODULE_AUTHOR("Gustavo Pimentel <gustavo.pimentel@synopsys.com>");