1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Intel Quadrature Encoder Peripheral driver |
4 | * |
5 | * Copyright (C) 2019-2021 Intel Corporation |
6 | * |
7 | * Author: Felipe Balbi (Intel) |
8 | * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com> |
9 | * Author: Raymond Tan <raymond.tan@intel.com> |
10 | */ |
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> |
17 | |
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 |
28 | |
29 | /* QEPCON */ |
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) |
49 | |
50 | /* QEPFLT */ |
51 | #define INTEL_QEPFLT_MAX_COUNT(n) ((n) & 0x1fffff) |
52 | |
53 | /* QEPINT */ |
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) |
60 | |
61 | #define INTEL_QEPINT_MASK_ALL GENMASK(5, 0) |
62 | |
63 | #define INTEL_QEP_CLK_PERIOD_NS 10 |
64 | |
65 | struct intel_qep { |
66 | struct mutex lock; |
67 | struct device *dev; |
68 | void __iomem *regs; |
69 | bool enabled; |
70 | /* Context save registers */ |
71 | u32 qepcon; |
72 | u32 qepflt; |
73 | u32 qepmax; |
74 | }; |
75 | |
76 | static inline u32 intel_qep_readl(struct intel_qep *qep, u32 offset) |
77 | { |
78 | return readl(addr: qep->regs + offset); |
79 | } |
80 | |
81 | static inline void intel_qep_writel(struct intel_qep *qep, |
82 | u32 offset, u32 value) |
83 | { |
84 | writel(val: value, addr: qep->regs + offset); |
85 | } |
86 | |
87 | static void intel_qep_init(struct intel_qep *qep) |
88 | { |
89 | u32 reg; |
90 | |
91 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
92 | reg &= ~INTEL_QEPCON_EN; |
93 | intel_qep_writel(qep, INTEL_QEPCON, value: reg); |
94 | qep->enabled = false; |
95 | /* |
96 | * Make sure peripheral is disabled by flushing the write with |
97 | * a dummy read |
98 | */ |
99 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
100 | |
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, value: reg); |
105 | intel_qep_writel(qep, INTEL_QEPINT_MASK, INTEL_QEPINT_MASK_ALL); |
106 | } |
107 | |
108 | static int intel_qep_count_read(struct counter_device *counter, |
109 | struct counter_count *count, u64 *val) |
110 | { |
111 | struct intel_qep *const qep = counter_priv(counter); |
112 | |
113 | pm_runtime_get_sync(dev: qep->dev); |
114 | *val = intel_qep_readl(qep, INTEL_QEPCOUNT); |
115 | pm_runtime_put(dev: qep->dev); |
116 | |
117 | return 0; |
118 | } |
119 | |
120 | static const enum counter_function intel_qep_count_functions[] = { |
121 | COUNTER_FUNCTION_QUADRATURE_X4, |
122 | }; |
123 | |
124 | static int intel_qep_function_read(struct counter_device *counter, |
125 | struct counter_count *count, |
126 | enum counter_function *function) |
127 | { |
128 | *function = COUNTER_FUNCTION_QUADRATURE_X4; |
129 | |
130 | return 0; |
131 | } |
132 | |
133 | static const enum counter_synapse_action intel_qep_synapse_actions[] = { |
134 | COUNTER_SYNAPSE_ACTION_BOTH_EDGES, |
135 | }; |
136 | |
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) |
141 | { |
142 | *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; |
143 | return 0; |
144 | } |
145 | |
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, |
150 | }; |
151 | |
152 | #define INTEL_QEP_SIGNAL(_id, _name) { \ |
153 | .id = (_id), \ |
154 | .name = (_name), \ |
155 | } |
156 | |
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" ), |
161 | }; |
162 | |
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)], \ |
167 | } |
168 | |
169 | static struct counter_synapse intel_qep_count_synapses[] = { |
170 | INTEL_QEP_SYNAPSE(0), |
171 | INTEL_QEP_SYNAPSE(1), |
172 | INTEL_QEP_SYNAPSE(2), |
173 | }; |
174 | |
175 | static int intel_qep_ceiling_read(struct counter_device *counter, |
176 | struct counter_count *count, u64 *ceiling) |
177 | { |
178 | struct intel_qep *qep = counter_priv(counter); |
179 | |
180 | pm_runtime_get_sync(dev: qep->dev); |
181 | *ceiling = intel_qep_readl(qep, INTEL_QEPMAX); |
182 | pm_runtime_put(dev: qep->dev); |
183 | |
184 | return 0; |
185 | } |
186 | |
187 | static int intel_qep_ceiling_write(struct counter_device *counter, |
188 | struct counter_count *count, u64 max) |
189 | { |
190 | struct intel_qep *qep = counter_priv(counter); |
191 | int ret = 0; |
192 | |
193 | /* Intel QEP ceiling configuration only supports 32-bit values */ |
194 | if (max != (u32)max) |
195 | return -ERANGE; |
196 | |
197 | mutex_lock(&qep->lock); |
198 | if (qep->enabled) { |
199 | ret = -EBUSY; |
200 | goto out; |
201 | } |
202 | |
203 | pm_runtime_get_sync(dev: qep->dev); |
204 | intel_qep_writel(qep, INTEL_QEPMAX, value: max); |
205 | pm_runtime_put(dev: qep->dev); |
206 | |
207 | out: |
208 | mutex_unlock(lock: &qep->lock); |
209 | return ret; |
210 | } |
211 | |
212 | static int intel_qep_enable_read(struct counter_device *counter, |
213 | struct counter_count *count, u8 *enable) |
214 | { |
215 | struct intel_qep *qep = counter_priv(counter); |
216 | |
217 | *enable = qep->enabled; |
218 | |
219 | return 0; |
220 | } |
221 | |
222 | static int intel_qep_enable_write(struct counter_device *counter, |
223 | struct counter_count *count, u8 val) |
224 | { |
225 | struct intel_qep *qep = counter_priv(counter); |
226 | u32 reg; |
227 | bool changed; |
228 | |
229 | mutex_lock(&qep->lock); |
230 | changed = val ^ qep->enabled; |
231 | if (!changed) |
232 | goto out; |
233 | |
234 | pm_runtime_get_sync(dev: qep->dev); |
235 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
236 | if (val) { |
237 | /* Enable peripheral and keep runtime PM always on */ |
238 | reg |= INTEL_QEPCON_EN; |
239 | pm_runtime_get_noresume(dev: qep->dev); |
240 | } else { |
241 | /* Let runtime PM be idle and disable peripheral */ |
242 | pm_runtime_put_noidle(dev: qep->dev); |
243 | reg &= ~INTEL_QEPCON_EN; |
244 | } |
245 | intel_qep_writel(qep, INTEL_QEPCON, value: reg); |
246 | pm_runtime_put(dev: qep->dev); |
247 | qep->enabled = val; |
248 | |
249 | out: |
250 | mutex_unlock(lock: &qep->lock); |
251 | return 0; |
252 | } |
253 | |
254 | static int intel_qep_spike_filter_ns_read(struct counter_device *counter, |
255 | struct counter_count *count, |
256 | u64 *length) |
257 | { |
258 | struct intel_qep *qep = counter_priv(counter); |
259 | u32 reg; |
260 | |
261 | pm_runtime_get_sync(dev: qep->dev); |
262 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
263 | if (!(reg & INTEL_QEPCON_FLT_EN)) { |
264 | pm_runtime_put(dev: qep->dev); |
265 | return 0; |
266 | } |
267 | reg = INTEL_QEPFLT_MAX_COUNT(intel_qep_readl(qep, INTEL_QEPFLT)); |
268 | pm_runtime_put(dev: qep->dev); |
269 | |
270 | *length = (reg + 2) * INTEL_QEP_CLK_PERIOD_NS; |
271 | |
272 | return 0; |
273 | } |
274 | |
275 | static int intel_qep_spike_filter_ns_write(struct counter_device *counter, |
276 | struct counter_count *count, |
277 | u64 length) |
278 | { |
279 | struct intel_qep *qep = counter_priv(counter); |
280 | u32 reg; |
281 | bool enable; |
282 | int ret = 0; |
283 | |
284 | /* |
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. |
288 | */ |
289 | do_div(length, INTEL_QEP_CLK_PERIOD_NS); |
290 | if (length == 0) { |
291 | enable = false; |
292 | length = 0; |
293 | } else if (length >= 2) { |
294 | enable = true; |
295 | length -= 2; |
296 | } else { |
297 | return -EINVAL; |
298 | } |
299 | |
300 | if (length > INTEL_QEPFLT_MAX_COUNT(length)) |
301 | return -ERANGE; |
302 | |
303 | mutex_lock(&qep->lock); |
304 | if (qep->enabled) { |
305 | ret = -EBUSY; |
306 | goto out; |
307 | } |
308 | |
309 | pm_runtime_get_sync(dev: qep->dev); |
310 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
311 | if (enable) |
312 | reg |= INTEL_QEPCON_FLT_EN; |
313 | else |
314 | reg &= ~INTEL_QEPCON_FLT_EN; |
315 | intel_qep_writel(qep, INTEL_QEPFLT, value: length); |
316 | intel_qep_writel(qep, INTEL_QEPCON, value: reg); |
317 | pm_runtime_put(dev: qep->dev); |
318 | |
319 | out: |
320 | mutex_unlock(lock: &qep->lock); |
321 | return ret; |
322 | } |
323 | |
324 | static int intel_qep_preset_enable_read(struct counter_device *counter, |
325 | struct counter_count *count, |
326 | u8 *preset_enable) |
327 | { |
328 | struct intel_qep *qep = counter_priv(counter); |
329 | u32 reg; |
330 | |
331 | pm_runtime_get_sync(dev: qep->dev); |
332 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
333 | pm_runtime_put(dev: qep->dev); |
334 | |
335 | *preset_enable = !(reg & INTEL_QEPCON_COUNT_RST_MODE); |
336 | |
337 | return 0; |
338 | } |
339 | |
340 | static int intel_qep_preset_enable_write(struct counter_device *counter, |
341 | struct counter_count *count, u8 val) |
342 | { |
343 | struct intel_qep *qep = counter_priv(counter); |
344 | u32 reg; |
345 | int ret = 0; |
346 | |
347 | mutex_lock(&qep->lock); |
348 | if (qep->enabled) { |
349 | ret = -EBUSY; |
350 | goto out; |
351 | } |
352 | |
353 | pm_runtime_get_sync(dev: qep->dev); |
354 | reg = intel_qep_readl(qep, INTEL_QEPCON); |
355 | if (val) |
356 | reg &= ~INTEL_QEPCON_COUNT_RST_MODE; |
357 | else |
358 | reg |= INTEL_QEPCON_COUNT_RST_MODE; |
359 | |
360 | intel_qep_writel(qep, INTEL_QEPCON, value: reg); |
361 | pm_runtime_put(dev: qep->dev); |
362 | |
363 | out: |
364 | mutex_unlock(lock: &qep->lock); |
365 | |
366 | return ret; |
367 | } |
368 | |
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), |
377 | }; |
378 | |
379 | static struct counter_count intel_qep_counter_count[] = { |
380 | { |
381 | .id = 0, |
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), |
389 | }, |
390 | }; |
391 | |
392 | static int intel_qep_probe(struct pci_dev *pci, const struct pci_device_id *id) |
393 | { |
394 | struct counter_device *counter; |
395 | struct intel_qep *qep; |
396 | struct device *dev = &pci->dev; |
397 | void __iomem *regs; |
398 | int ret; |
399 | |
400 | counter = devm_counter_alloc(dev, sizeof_priv: sizeof(*qep)); |
401 | if (!counter) |
402 | return -ENOMEM; |
403 | qep = counter_priv(counter); |
404 | |
405 | ret = pcim_enable_device(pdev: pci); |
406 | if (ret) |
407 | return ret; |
408 | |
409 | pci_set_master(dev: pci); |
410 | |
411 | ret = pcim_iomap_regions(pdev: pci, BIT(0), name: pci_name(pdev: pci)); |
412 | if (ret) |
413 | return ret; |
414 | |
415 | regs = pcim_iomap_table(pdev: pci)[0]; |
416 | if (!regs) |
417 | return -ENOMEM; |
418 | |
419 | qep->dev = dev; |
420 | qep->regs = regs; |
421 | mutex_init(&qep->lock); |
422 | |
423 | intel_qep_init(qep); |
424 | pci_set_drvdata(pdev: pci, data: qep); |
425 | |
426 | counter->name = pci_name(pdev: pci); |
427 | counter->parent = dev; |
428 | counter->ops = &intel_qep_counter_ops; |
429 | counter->counts = intel_qep_counter_count; |
430 | counter->num_counts = ARRAY_SIZE(intel_qep_counter_count); |
431 | counter->signals = intel_qep_signals; |
432 | counter->num_signals = ARRAY_SIZE(intel_qep_signals); |
433 | qep->enabled = false; |
434 | |
435 | pm_runtime_put(dev); |
436 | pm_runtime_allow(dev); |
437 | |
438 | ret = devm_counter_add(dev: &pci->dev, counter); |
439 | if (ret < 0) |
440 | return dev_err_probe(dev: &pci->dev, err: ret, fmt: "Failed to add counter\n" ); |
441 | |
442 | return 0; |
443 | } |
444 | |
445 | static void intel_qep_remove(struct pci_dev *pci) |
446 | { |
447 | struct intel_qep *qep = pci_get_drvdata(pdev: pci); |
448 | struct device *dev = &pci->dev; |
449 | |
450 | pm_runtime_forbid(dev); |
451 | if (!qep->enabled) |
452 | pm_runtime_get(dev); |
453 | |
454 | intel_qep_writel(qep, INTEL_QEPCON, value: 0); |
455 | } |
456 | |
457 | static int __maybe_unused intel_qep_suspend(struct device *dev) |
458 | { |
459 | struct pci_dev *pdev = to_pci_dev(dev); |
460 | struct intel_qep *qep = pci_get_drvdata(pdev); |
461 | |
462 | qep->qepcon = intel_qep_readl(qep, INTEL_QEPCON); |
463 | qep->qepflt = intel_qep_readl(qep, INTEL_QEPFLT); |
464 | qep->qepmax = intel_qep_readl(qep, INTEL_QEPMAX); |
465 | |
466 | return 0; |
467 | } |
468 | |
469 | static int __maybe_unused intel_qep_resume(struct device *dev) |
470 | { |
471 | struct pci_dev *pdev = to_pci_dev(dev); |
472 | struct intel_qep *qep = pci_get_drvdata(pdev); |
473 | |
474 | /* |
475 | * Make sure peripheral is disabled when restoring registers and |
476 | * control register bits that are writable only when the peripheral |
477 | * is disabled |
478 | */ |
479 | intel_qep_writel(qep, INTEL_QEPCON, value: 0); |
480 | intel_qep_readl(qep, INTEL_QEPCON); |
481 | |
482 | intel_qep_writel(qep, INTEL_QEPFLT, value: qep->qepflt); |
483 | intel_qep_writel(qep, INTEL_QEPMAX, value: qep->qepmax); |
484 | intel_qep_writel(qep, INTEL_QEPINT_MASK, INTEL_QEPINT_MASK_ALL); |
485 | |
486 | /* Restore all other control register bits except enable status */ |
487 | intel_qep_writel(qep, INTEL_QEPCON, value: qep->qepcon & ~INTEL_QEPCON_EN); |
488 | intel_qep_readl(qep, INTEL_QEPCON); |
489 | |
490 | /* Restore enable status */ |
491 | intel_qep_writel(qep, INTEL_QEPCON, value: qep->qepcon); |
492 | |
493 | return 0; |
494 | } |
495 | |
496 | static UNIVERSAL_DEV_PM_OPS(intel_qep_pm_ops, |
497 | intel_qep_suspend, intel_qep_resume, NULL); |
498 | |
499 | static const struct pci_device_id intel_qep_id_table[] = { |
500 | /* EHL */ |
501 | { PCI_VDEVICE(INTEL, 0x4bc3), }, |
502 | { PCI_VDEVICE(INTEL, 0x4b81), }, |
503 | { PCI_VDEVICE(INTEL, 0x4b82), }, |
504 | { PCI_VDEVICE(INTEL, 0x4b83), }, |
505 | { } /* Terminating Entry */ |
506 | }; |
507 | MODULE_DEVICE_TABLE(pci, intel_qep_id_table); |
508 | |
509 | static struct pci_driver intel_qep_driver = { |
510 | .name = "intel-qep" , |
511 | .id_table = intel_qep_id_table, |
512 | .probe = intel_qep_probe, |
513 | .remove = intel_qep_remove, |
514 | .driver = { |
515 | .pm = &intel_qep_pm_ops, |
516 | } |
517 | }; |
518 | |
519 | module_pci_driver(intel_qep_driver); |
520 | |
521 | MODULE_AUTHOR("Felipe Balbi (Intel)" ); |
522 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>" ); |
523 | MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>" ); |
524 | MODULE_LICENSE("GPL" ); |
525 | MODULE_DESCRIPTION("Intel Quadrature Encoder Peripheral driver" ); |
526 | MODULE_IMPORT_NS(COUNTER); |
527 | |