1 // SPDX-License-Identifier: GPL-2.0
3 * Intel Quadrature Encoder Peripheral driver
5 * Copyright (C) 2019-2021 Intel Corporation
7 * Author: Felipe Balbi (Intel)
8 * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
9 * Author: Raymond Tan <raymond.tan@intel.com>
11 #include <linux/counter.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/pci.h>
16 #include <linux/pm_runtime.h>
18 #define INTEL_QEPCON 0x00
19 #define INTEL_QEPFLT 0x04
20 #define INTEL_QEPCOUNT 0x08
21 #define INTEL_QEPMAX 0x0c
22 #define INTEL_QEPWDT 0x10
23 #define INTEL_QEPCAPDIV 0x14
24 #define INTEL_QEPCNTR 0x18
25 #define INTEL_QEPCAPBUF 0x1c
26 #define INTEL_QEPINT_STAT 0x20
27 #define INTEL_QEPINT_MASK 0x24
30 #define INTEL_QEPCON_EN BIT(0)
31 #define INTEL_QEPCON_FLT_EN BIT(1)
32 #define INTEL_QEPCON_EDGE_A BIT(2)
33 #define INTEL_QEPCON_EDGE_B BIT(3)
34 #define INTEL_QEPCON_EDGE_INDX BIT(4)
35 #define INTEL_QEPCON_SWPAB BIT(5)
36 #define INTEL_QEPCON_OP_MODE BIT(6)
37 #define INTEL_QEPCON_PH_ERR BIT(7)
38 #define INTEL_QEPCON_COUNT_RST_MODE BIT(8)
39 #define INTEL_QEPCON_INDX_GATING_MASK GENMASK(10, 9)
40 #define INTEL_QEPCON_INDX_GATING(n) (((n) & 3) << 9)
41 #define INTEL_QEPCON_INDX_PAL_PBL INTEL_QEPCON_INDX_GATING(0)
42 #define INTEL_QEPCON_INDX_PAL_PBH INTEL_QEPCON_INDX_GATING(1)
43 #define INTEL_QEPCON_INDX_PAH_PBL INTEL_QEPCON_INDX_GATING(2)
44 #define INTEL_QEPCON_INDX_PAH_PBH INTEL_QEPCON_INDX_GATING(3)
45 #define INTEL_QEPCON_CAP_MODE BIT(11)
46 #define INTEL_QEPCON_FIFO_THRE_MASK GENMASK(14, 12)
47 #define INTEL_QEPCON_FIFO_THRE(n) ((((n) - 1) & 7) << 12)
48 #define INTEL_QEPCON_FIFO_EMPTY BIT(15)
51 #define INTEL_QEPFLT_MAX_COUNT(n) ((n) & 0x1fffff)
54 #define INTEL_QEPINT_FIFOCRIT BIT(5)
55 #define INTEL_QEPINT_FIFOENTRY BIT(4)
56 #define INTEL_QEPINT_QEPDIR BIT(3)
57 #define INTEL_QEPINT_QEPRST_UP BIT(2)
58 #define INTEL_QEPINT_QEPRST_DOWN BIT(1)
59 #define INTEL_QEPINT_WDT BIT(0)
61 #define INTEL_QEPINT_MASK_ALL GENMASK(5, 0)
63 #define INTEL_QEP_CLK_PERIOD_NS 10
70 /* Context save registers */
76 static inline u32
intel_qep_readl(struct intel_qep
*qep
, u32 offset
)
78 return readl(qep
->regs
+ offset
);
81 static inline void intel_qep_writel(struct intel_qep
*qep
,
82 u32 offset
, u32 value
)
84 writel(value
, qep
->regs
+ offset
);
87 static void intel_qep_init(struct intel_qep
*qep
)
91 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
92 reg
&= ~INTEL_QEPCON_EN
;
93 intel_qep_writel(qep
, INTEL_QEPCON
, reg
);
96 * Make sure peripheral is disabled by flushing the write with
99 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
101 reg
&= ~(INTEL_QEPCON_OP_MODE
| INTEL_QEPCON_FLT_EN
);
102 reg
|= INTEL_QEPCON_EDGE_A
| INTEL_QEPCON_EDGE_B
|
103 INTEL_QEPCON_EDGE_INDX
| INTEL_QEPCON_COUNT_RST_MODE
;
104 intel_qep_writel(qep
, INTEL_QEPCON
, reg
);
105 intel_qep_writel(qep
, INTEL_QEPINT_MASK
, INTEL_QEPINT_MASK_ALL
);
108 static int intel_qep_count_read(struct counter_device
*counter
,
109 struct counter_count
*count
, u64
*val
)
111 struct intel_qep
*const qep
= counter_priv(counter
);
113 pm_runtime_get_sync(qep
->dev
);
114 *val
= intel_qep_readl(qep
, INTEL_QEPCOUNT
);
115 pm_runtime_put(qep
->dev
);
120 static const enum counter_function intel_qep_count_functions
[] = {
121 COUNTER_FUNCTION_QUADRATURE_X4
,
124 static int intel_qep_function_read(struct counter_device
*counter
,
125 struct counter_count
*count
,
126 enum counter_function
*function
)
128 *function
= COUNTER_FUNCTION_QUADRATURE_X4
;
133 static const enum counter_synapse_action intel_qep_synapse_actions
[] = {
134 COUNTER_SYNAPSE_ACTION_BOTH_EDGES
,
137 static int intel_qep_action_read(struct counter_device
*counter
,
138 struct counter_count
*count
,
139 struct counter_synapse
*synapse
,
140 enum counter_synapse_action
*action
)
142 *action
= COUNTER_SYNAPSE_ACTION_BOTH_EDGES
;
146 static const struct counter_ops intel_qep_counter_ops
= {
147 .count_read
= intel_qep_count_read
,
148 .function_read
= intel_qep_function_read
,
149 .action_read
= intel_qep_action_read
,
152 #define INTEL_QEP_SIGNAL(_id, _name) { \
157 static struct counter_signal intel_qep_signals
[] = {
158 INTEL_QEP_SIGNAL(0, "Phase A"),
159 INTEL_QEP_SIGNAL(1, "Phase B"),
160 INTEL_QEP_SIGNAL(2, "Index"),
163 #define INTEL_QEP_SYNAPSE(_signal_id) { \
164 .actions_list = intel_qep_synapse_actions, \
165 .num_actions = ARRAY_SIZE(intel_qep_synapse_actions), \
166 .signal = &intel_qep_signals[(_signal_id)], \
169 static struct counter_synapse intel_qep_count_synapses
[] = {
170 INTEL_QEP_SYNAPSE(0),
171 INTEL_QEP_SYNAPSE(1),
172 INTEL_QEP_SYNAPSE(2),
175 static int intel_qep_ceiling_read(struct counter_device
*counter
,
176 struct counter_count
*count
, u64
*ceiling
)
178 struct intel_qep
*qep
= counter_priv(counter
);
180 pm_runtime_get_sync(qep
->dev
);
181 *ceiling
= intel_qep_readl(qep
, INTEL_QEPMAX
);
182 pm_runtime_put(qep
->dev
);
187 static int intel_qep_ceiling_write(struct counter_device
*counter
,
188 struct counter_count
*count
, u64 max
)
190 struct intel_qep
*qep
= counter_priv(counter
);
193 /* Intel QEP ceiling configuration only supports 32-bit values */
197 mutex_lock(&qep
->lock
);
203 pm_runtime_get_sync(qep
->dev
);
204 intel_qep_writel(qep
, INTEL_QEPMAX
, max
);
205 pm_runtime_put(qep
->dev
);
208 mutex_unlock(&qep
->lock
);
212 static int intel_qep_enable_read(struct counter_device
*counter
,
213 struct counter_count
*count
, u8
*enable
)
215 struct intel_qep
*qep
= counter_priv(counter
);
217 *enable
= qep
->enabled
;
222 static int intel_qep_enable_write(struct counter_device
*counter
,
223 struct counter_count
*count
, u8 val
)
225 struct intel_qep
*qep
= counter_priv(counter
);
229 mutex_lock(&qep
->lock
);
230 changed
= val
^ qep
->enabled
;
234 pm_runtime_get_sync(qep
->dev
);
235 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
237 /* Enable peripheral and keep runtime PM always on */
238 reg
|= INTEL_QEPCON_EN
;
239 pm_runtime_get_noresume(qep
->dev
);
241 /* Let runtime PM be idle and disable peripheral */
242 pm_runtime_put_noidle(qep
->dev
);
243 reg
&= ~INTEL_QEPCON_EN
;
245 intel_qep_writel(qep
, INTEL_QEPCON
, reg
);
246 pm_runtime_put(qep
->dev
);
250 mutex_unlock(&qep
->lock
);
254 static int intel_qep_spike_filter_ns_read(struct counter_device
*counter
,
255 struct counter_count
*count
,
258 struct intel_qep
*qep
= counter_priv(counter
);
261 pm_runtime_get_sync(qep
->dev
);
262 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
263 if (!(reg
& INTEL_QEPCON_FLT_EN
)) {
264 pm_runtime_put(qep
->dev
);
267 reg
= INTEL_QEPFLT_MAX_COUNT(intel_qep_readl(qep
, INTEL_QEPFLT
));
268 pm_runtime_put(qep
->dev
);
270 *length
= (reg
+ 2) * INTEL_QEP_CLK_PERIOD_NS
;
275 static int intel_qep_spike_filter_ns_write(struct counter_device
*counter
,
276 struct counter_count
*count
,
279 struct intel_qep
*qep
= counter_priv(counter
);
285 * Spike filter length is (MAX_COUNT + 2) clock periods.
286 * Disable filter when userspace writes 0, enable for valid
287 * nanoseconds values and error out otherwise.
289 do_div(length
, INTEL_QEP_CLK_PERIOD_NS
);
293 } else if (length
>= 2) {
300 if (length
> INTEL_QEPFLT_MAX_COUNT(length
))
303 mutex_lock(&qep
->lock
);
309 pm_runtime_get_sync(qep
->dev
);
310 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
312 reg
|= INTEL_QEPCON_FLT_EN
;
314 reg
&= ~INTEL_QEPCON_FLT_EN
;
315 intel_qep_writel(qep
, INTEL_QEPFLT
, length
);
316 intel_qep_writel(qep
, INTEL_QEPCON
, reg
);
317 pm_runtime_put(qep
->dev
);
320 mutex_unlock(&qep
->lock
);
324 static int intel_qep_preset_enable_read(struct counter_device
*counter
,
325 struct counter_count
*count
,
328 struct intel_qep
*qep
= counter_priv(counter
);
331 pm_runtime_get_sync(qep
->dev
);
332 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
333 pm_runtime_put(qep
->dev
);
335 *preset_enable
= !(reg
& INTEL_QEPCON_COUNT_RST_MODE
);
340 static int intel_qep_preset_enable_write(struct counter_device
*counter
,
341 struct counter_count
*count
, u8 val
)
343 struct intel_qep
*qep
= counter_priv(counter
);
347 mutex_lock(&qep
->lock
);
353 pm_runtime_get_sync(qep
->dev
);
354 reg
= intel_qep_readl(qep
, INTEL_QEPCON
);
356 reg
&= ~INTEL_QEPCON_COUNT_RST_MODE
;
358 reg
|= INTEL_QEPCON_COUNT_RST_MODE
;
360 intel_qep_writel(qep
, INTEL_QEPCON
, reg
);
361 pm_runtime_put(qep
->dev
);
364 mutex_unlock(&qep
->lock
);
369 static struct counter_comp intel_qep_count_ext
[] = {
370 COUNTER_COMP_ENABLE(intel_qep_enable_read
, intel_qep_enable_write
),
371 COUNTER_COMP_CEILING(intel_qep_ceiling_read
, intel_qep_ceiling_write
),
372 COUNTER_COMP_PRESET_ENABLE(intel_qep_preset_enable_read
,
373 intel_qep_preset_enable_write
),
374 COUNTER_COMP_COUNT_U64("spike_filter_ns",
375 intel_qep_spike_filter_ns_read
,
376 intel_qep_spike_filter_ns_write
),
379 static struct counter_count intel_qep_counter_count
[] = {
382 .name
= "Channel 1 Count",
383 .functions_list
= intel_qep_count_functions
,
384 .num_functions
= ARRAY_SIZE(intel_qep_count_functions
),
385 .synapses
= intel_qep_count_synapses
,
386 .num_synapses
= ARRAY_SIZE(intel_qep_count_synapses
),
387 .ext
= intel_qep_count_ext
,
388 .num_ext
= ARRAY_SIZE(intel_qep_count_ext
),
392 static int intel_qep_probe(struct pci_dev
*pci
, const struct pci_device_id
*id
)
394 struct counter_device
*counter
;
395 struct intel_qep
*qep
;
396 struct device
*dev
= &pci
->dev
;
400 counter
= devm_counter_alloc(dev
, sizeof(*qep
));
403 qep
= counter_priv(counter
);
405 ret
= pcim_enable_device(pci
);
411 regs
= pcim_iomap_region(pci
, 0, pci_name(pci
));
413 return PTR_ERR(regs
);
417 mutex_init(&qep
->lock
);
420 pci_set_drvdata(pci
, qep
);
422 counter
->name
= pci_name(pci
);
423 counter
->parent
= dev
;
424 counter
->ops
= &intel_qep_counter_ops
;
425 counter
->counts
= intel_qep_counter_count
;
426 counter
->num_counts
= ARRAY_SIZE(intel_qep_counter_count
);
427 counter
->signals
= intel_qep_signals
;
428 counter
->num_signals
= ARRAY_SIZE(intel_qep_signals
);
429 qep
->enabled
= false;
432 pm_runtime_allow(dev
);
434 ret
= devm_counter_add(&pci
->dev
, counter
);
436 return dev_err_probe(&pci
->dev
, ret
, "Failed to add counter\n");
441 static void intel_qep_remove(struct pci_dev
*pci
)
443 struct intel_qep
*qep
= pci_get_drvdata(pci
);
444 struct device
*dev
= &pci
->dev
;
446 pm_runtime_forbid(dev
);
450 intel_qep_writel(qep
, INTEL_QEPCON
, 0);
453 static int __maybe_unused
intel_qep_suspend(struct device
*dev
)
455 struct pci_dev
*pdev
= to_pci_dev(dev
);
456 struct intel_qep
*qep
= pci_get_drvdata(pdev
);
458 qep
->qepcon
= intel_qep_readl(qep
, INTEL_QEPCON
);
459 qep
->qepflt
= intel_qep_readl(qep
, INTEL_QEPFLT
);
460 qep
->qepmax
= intel_qep_readl(qep
, INTEL_QEPMAX
);
465 static int __maybe_unused
intel_qep_resume(struct device
*dev
)
467 struct pci_dev
*pdev
= to_pci_dev(dev
);
468 struct intel_qep
*qep
= pci_get_drvdata(pdev
);
471 * Make sure peripheral is disabled when restoring registers and
472 * control register bits that are writable only when the peripheral
475 intel_qep_writel(qep
, INTEL_QEPCON
, 0);
476 intel_qep_readl(qep
, INTEL_QEPCON
);
478 intel_qep_writel(qep
, INTEL_QEPFLT
, qep
->qepflt
);
479 intel_qep_writel(qep
, INTEL_QEPMAX
, qep
->qepmax
);
480 intel_qep_writel(qep
, INTEL_QEPINT_MASK
, INTEL_QEPINT_MASK_ALL
);
482 /* Restore all other control register bits except enable status */
483 intel_qep_writel(qep
, INTEL_QEPCON
, qep
->qepcon
& ~INTEL_QEPCON_EN
);
484 intel_qep_readl(qep
, INTEL_QEPCON
);
486 /* Restore enable status */
487 intel_qep_writel(qep
, INTEL_QEPCON
, qep
->qepcon
);
492 static UNIVERSAL_DEV_PM_OPS(intel_qep_pm_ops
,
493 intel_qep_suspend
, intel_qep_resume
, NULL
);
495 static const struct pci_device_id intel_qep_id_table
[] = {
497 { PCI_VDEVICE(INTEL
, 0x4bc3), },
498 { PCI_VDEVICE(INTEL
, 0x4b81), },
499 { PCI_VDEVICE(INTEL
, 0x4b82), },
500 { PCI_VDEVICE(INTEL
, 0x4b83), },
501 { } /* Terminating Entry */
503 MODULE_DEVICE_TABLE(pci
, intel_qep_id_table
);
505 static struct pci_driver intel_qep_driver
= {
507 .id_table
= intel_qep_id_table
,
508 .probe
= intel_qep_probe
,
509 .remove
= intel_qep_remove
,
511 .pm
= &intel_qep_pm_ops
,
515 module_pci_driver(intel_qep_driver
);
517 MODULE_AUTHOR("Felipe Balbi (Intel)");
518 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
519 MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
520 MODULE_LICENSE("GPL");
521 MODULE_DESCRIPTION("Intel Quadrature Encoder Peripheral driver");
522 MODULE_IMPORT_NS("COUNTER");