Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Intel Quadrature Encoder Peripheral driver
0004  *
0005  * Copyright (C) 2019-2021 Intel Corporation
0006  *
0007  * Author: Felipe Balbi (Intel)
0008  * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
0009  * Author: Raymond Tan <raymond.tan@intel.com>
0010  */
0011 #include <linux/counter.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/mutex.h>
0015 #include <linux/pci.h>
0016 #include <linux/pm_runtime.h>
0017 
0018 #define INTEL_QEPCON            0x00
0019 #define INTEL_QEPFLT            0x04
0020 #define INTEL_QEPCOUNT          0x08
0021 #define INTEL_QEPMAX            0x0c
0022 #define INTEL_QEPWDT            0x10
0023 #define INTEL_QEPCAPDIV         0x14
0024 #define INTEL_QEPCNTR           0x18
0025 #define INTEL_QEPCAPBUF         0x1c
0026 #define INTEL_QEPINT_STAT       0x20
0027 #define INTEL_QEPINT_MASK       0x24
0028 
0029 /* QEPCON */
0030 #define INTEL_QEPCON_EN         BIT(0)
0031 #define INTEL_QEPCON_FLT_EN     BIT(1)
0032 #define INTEL_QEPCON_EDGE_A     BIT(2)
0033 #define INTEL_QEPCON_EDGE_B     BIT(3)
0034 #define INTEL_QEPCON_EDGE_INDX      BIT(4)
0035 #define INTEL_QEPCON_SWPAB      BIT(5)
0036 #define INTEL_QEPCON_OP_MODE        BIT(6)
0037 #define INTEL_QEPCON_PH_ERR     BIT(7)
0038 #define INTEL_QEPCON_COUNT_RST_MODE BIT(8)
0039 #define INTEL_QEPCON_INDX_GATING_MASK   GENMASK(10, 9)
0040 #define INTEL_QEPCON_INDX_GATING(n) (((n) & 3) << 9)
0041 #define INTEL_QEPCON_INDX_PAL_PBL   INTEL_QEPCON_INDX_GATING(0)
0042 #define INTEL_QEPCON_INDX_PAL_PBH   INTEL_QEPCON_INDX_GATING(1)
0043 #define INTEL_QEPCON_INDX_PAH_PBL   INTEL_QEPCON_INDX_GATING(2)
0044 #define INTEL_QEPCON_INDX_PAH_PBH   INTEL_QEPCON_INDX_GATING(3)
0045 #define INTEL_QEPCON_CAP_MODE       BIT(11)
0046 #define INTEL_QEPCON_FIFO_THRE_MASK GENMASK(14, 12)
0047 #define INTEL_QEPCON_FIFO_THRE(n)   ((((n) - 1) & 7) << 12)
0048 #define INTEL_QEPCON_FIFO_EMPTY     BIT(15)
0049 
0050 /* QEPFLT */
0051 #define INTEL_QEPFLT_MAX_COUNT(n)   ((n) & 0x1fffff)
0052 
0053 /* QEPINT */
0054 #define INTEL_QEPINT_FIFOCRIT       BIT(5)
0055 #define INTEL_QEPINT_FIFOENTRY      BIT(4)
0056 #define INTEL_QEPINT_QEPDIR     BIT(3)
0057 #define INTEL_QEPINT_QEPRST_UP      BIT(2)
0058 #define INTEL_QEPINT_QEPRST_DOWN    BIT(1)
0059 #define INTEL_QEPINT_WDT        BIT(0)
0060 
0061 #define INTEL_QEPINT_MASK_ALL       GENMASK(5, 0)
0062 
0063 #define INTEL_QEP_CLK_PERIOD_NS     10
0064 
0065 struct intel_qep {
0066     struct mutex lock;
0067     struct device *dev;
0068     void __iomem *regs;
0069     bool enabled;
0070     /* Context save registers */
0071     u32 qepcon;
0072     u32 qepflt;
0073     u32 qepmax;
0074 };
0075 
0076 static inline u32 intel_qep_readl(struct intel_qep *qep, u32 offset)
0077 {
0078     return readl(qep->regs + offset);
0079 }
0080 
0081 static inline void intel_qep_writel(struct intel_qep *qep,
0082                     u32 offset, u32 value)
0083 {
0084     writel(value, qep->regs + offset);
0085 }
0086 
0087 static void intel_qep_init(struct intel_qep *qep)
0088 {
0089     u32 reg;
0090 
0091     reg = intel_qep_readl(qep, INTEL_QEPCON);
0092     reg &= ~INTEL_QEPCON_EN;
0093     intel_qep_writel(qep, INTEL_QEPCON, reg);
0094     qep->enabled = false;
0095     /*
0096      * Make sure peripheral is disabled by flushing the write with
0097      * a dummy read
0098      */
0099     reg = intel_qep_readl(qep, INTEL_QEPCON);
0100 
0101     reg &= ~(INTEL_QEPCON_OP_MODE | INTEL_QEPCON_FLT_EN);
0102     reg |= INTEL_QEPCON_EDGE_A | INTEL_QEPCON_EDGE_B |
0103            INTEL_QEPCON_EDGE_INDX | INTEL_QEPCON_COUNT_RST_MODE;
0104     intel_qep_writel(qep, INTEL_QEPCON, reg);
0105     intel_qep_writel(qep, INTEL_QEPINT_MASK, INTEL_QEPINT_MASK_ALL);
0106 }
0107 
0108 static int intel_qep_count_read(struct counter_device *counter,
0109                 struct counter_count *count, u64 *val)
0110 {
0111     struct intel_qep *const qep = counter_priv(counter);
0112 
0113     pm_runtime_get_sync(qep->dev);
0114     *val = intel_qep_readl(qep, INTEL_QEPCOUNT);
0115     pm_runtime_put(qep->dev);
0116 
0117     return 0;
0118 }
0119 
0120 static const enum counter_function intel_qep_count_functions[] = {
0121     COUNTER_FUNCTION_QUADRATURE_X4,
0122 };
0123 
0124 static int intel_qep_function_read(struct counter_device *counter,
0125                    struct counter_count *count,
0126                    enum counter_function *function)
0127 {
0128     *function = COUNTER_FUNCTION_QUADRATURE_X4;
0129 
0130     return 0;
0131 }
0132 
0133 static const enum counter_synapse_action intel_qep_synapse_actions[] = {
0134     COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
0135 };
0136 
0137 static int intel_qep_action_read(struct counter_device *counter,
0138                  struct counter_count *count,
0139                  struct counter_synapse *synapse,
0140                  enum counter_synapse_action *action)
0141 {
0142     *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
0143     return 0;
0144 }
0145 
0146 static const struct counter_ops intel_qep_counter_ops = {
0147     .count_read = intel_qep_count_read,
0148     .function_read = intel_qep_function_read,
0149     .action_read = intel_qep_action_read,
0150 };
0151 
0152 #define INTEL_QEP_SIGNAL(_id, _name) {              \
0153     .id = (_id),                        \
0154     .name = (_name),                    \
0155 }
0156 
0157 static struct counter_signal intel_qep_signals[] = {
0158     INTEL_QEP_SIGNAL(0, "Phase A"),
0159     INTEL_QEP_SIGNAL(1, "Phase B"),
0160     INTEL_QEP_SIGNAL(2, "Index"),
0161 };
0162 
0163 #define INTEL_QEP_SYNAPSE(_signal_id) {             \
0164     .actions_list = intel_qep_synapse_actions,      \
0165     .num_actions = ARRAY_SIZE(intel_qep_synapse_actions),   \
0166     .signal = &intel_qep_signals[(_signal_id)],     \
0167 }
0168 
0169 static struct counter_synapse intel_qep_count_synapses[] = {
0170     INTEL_QEP_SYNAPSE(0),
0171     INTEL_QEP_SYNAPSE(1),
0172     INTEL_QEP_SYNAPSE(2),
0173 };
0174 
0175 static int intel_qep_ceiling_read(struct counter_device *counter,
0176                   struct counter_count *count, u64 *ceiling)
0177 {
0178     struct intel_qep *qep = counter_priv(counter);
0179 
0180     pm_runtime_get_sync(qep->dev);
0181     *ceiling = intel_qep_readl(qep, INTEL_QEPMAX);
0182     pm_runtime_put(qep->dev);
0183 
0184     return 0;
0185 }
0186 
0187 static int intel_qep_ceiling_write(struct counter_device *counter,
0188                    struct counter_count *count, u64 max)
0189 {
0190     struct intel_qep *qep = counter_priv(counter);
0191     int ret = 0;
0192 
0193     /* Intel QEP ceiling configuration only supports 32-bit values */
0194     if (max != (u32)max)
0195         return -ERANGE;
0196 
0197     mutex_lock(&qep->lock);
0198     if (qep->enabled) {
0199         ret = -EBUSY;
0200         goto out;
0201     }
0202 
0203     pm_runtime_get_sync(qep->dev);
0204     intel_qep_writel(qep, INTEL_QEPMAX, max);
0205     pm_runtime_put(qep->dev);
0206 
0207 out:
0208     mutex_unlock(&qep->lock);
0209     return ret;
0210 }
0211 
0212 static int intel_qep_enable_read(struct counter_device *counter,
0213                  struct counter_count *count, u8 *enable)
0214 {
0215     struct intel_qep *qep = counter_priv(counter);
0216 
0217     *enable = qep->enabled;
0218 
0219     return 0;
0220 }
0221 
0222 static int intel_qep_enable_write(struct counter_device *counter,
0223                   struct counter_count *count, u8 val)
0224 {
0225     struct intel_qep *qep = counter_priv(counter);
0226     u32 reg;
0227     bool changed;
0228 
0229     mutex_lock(&qep->lock);
0230     changed = val ^ qep->enabled;
0231     if (!changed)
0232         goto out;
0233 
0234     pm_runtime_get_sync(qep->dev);
0235     reg = intel_qep_readl(qep, INTEL_QEPCON);
0236     if (val) {
0237         /* Enable peripheral and keep runtime PM always on */
0238         reg |= INTEL_QEPCON_EN;
0239         pm_runtime_get_noresume(qep->dev);
0240     } else {
0241         /* Let runtime PM be idle and disable peripheral */
0242         pm_runtime_put_noidle(qep->dev);
0243         reg &= ~INTEL_QEPCON_EN;
0244     }
0245     intel_qep_writel(qep, INTEL_QEPCON, reg);
0246     pm_runtime_put(qep->dev);
0247     qep->enabled = val;
0248 
0249 out:
0250     mutex_unlock(&qep->lock);
0251     return 0;
0252 }
0253 
0254 static int intel_qep_spike_filter_ns_read(struct counter_device *counter,
0255                       struct counter_count *count,
0256                       u64 *length)
0257 {
0258     struct intel_qep *qep = counter_priv(counter);
0259     u32 reg;
0260 
0261     pm_runtime_get_sync(qep->dev);
0262     reg = intel_qep_readl(qep, INTEL_QEPCON);
0263     if (!(reg & INTEL_QEPCON_FLT_EN)) {
0264         pm_runtime_put(qep->dev);
0265         return 0;
0266     }
0267     reg = INTEL_QEPFLT_MAX_COUNT(intel_qep_readl(qep, INTEL_QEPFLT));
0268     pm_runtime_put(qep->dev);
0269 
0270     *length = (reg + 2) * INTEL_QEP_CLK_PERIOD_NS;
0271 
0272     return 0;
0273 }
0274 
0275 static int intel_qep_spike_filter_ns_write(struct counter_device *counter,
0276                        struct counter_count *count,
0277                        u64 length)
0278 {
0279     struct intel_qep *qep = counter_priv(counter);
0280     u32 reg;
0281     bool enable;
0282     int ret = 0;
0283 
0284     /*
0285      * Spike filter length is (MAX_COUNT + 2) clock periods.
0286      * Disable filter when userspace writes 0, enable for valid
0287      * nanoseconds values and error out otherwise.
0288      */
0289     do_div(length, INTEL_QEP_CLK_PERIOD_NS);
0290     if (length == 0) {
0291         enable = false;
0292         length = 0;
0293     } else if (length >= 2) {
0294         enable = true;
0295         length -= 2;
0296     } else {
0297         return -EINVAL;
0298     }
0299 
0300     if (length > INTEL_QEPFLT_MAX_COUNT(length))
0301         return -ERANGE;
0302 
0303     mutex_lock(&qep->lock);
0304     if (qep->enabled) {
0305         ret = -EBUSY;
0306         goto out;
0307     }
0308 
0309     pm_runtime_get_sync(qep->dev);
0310     reg = intel_qep_readl(qep, INTEL_QEPCON);
0311     if (enable)
0312         reg |= INTEL_QEPCON_FLT_EN;
0313     else
0314         reg &= ~INTEL_QEPCON_FLT_EN;
0315     intel_qep_writel(qep, INTEL_QEPFLT, length);
0316     intel_qep_writel(qep, INTEL_QEPCON, reg);
0317     pm_runtime_put(qep->dev);
0318 
0319 out:
0320     mutex_unlock(&qep->lock);
0321     return ret;
0322 }
0323 
0324 static int intel_qep_preset_enable_read(struct counter_device *counter,
0325                     struct counter_count *count,
0326                     u8 *preset_enable)
0327 {
0328     struct intel_qep *qep = counter_priv(counter);
0329     u32 reg;
0330 
0331     pm_runtime_get_sync(qep->dev);
0332     reg = intel_qep_readl(qep, INTEL_QEPCON);
0333     pm_runtime_put(qep->dev);
0334 
0335     *preset_enable = !(reg & INTEL_QEPCON_COUNT_RST_MODE);
0336 
0337     return 0;
0338 }
0339 
0340 static int intel_qep_preset_enable_write(struct counter_device *counter,
0341                      struct counter_count *count, u8 val)
0342 {
0343     struct intel_qep *qep = counter_priv(counter);
0344     u32 reg;
0345     int ret = 0;
0346 
0347     mutex_lock(&qep->lock);
0348     if (qep->enabled) {
0349         ret = -EBUSY;
0350         goto out;
0351     }
0352 
0353     pm_runtime_get_sync(qep->dev);
0354     reg = intel_qep_readl(qep, INTEL_QEPCON);
0355     if (val)
0356         reg &= ~INTEL_QEPCON_COUNT_RST_MODE;
0357     else
0358         reg |= INTEL_QEPCON_COUNT_RST_MODE;
0359 
0360     intel_qep_writel(qep, INTEL_QEPCON, reg);
0361     pm_runtime_put(qep->dev);
0362 
0363 out:
0364     mutex_unlock(&qep->lock);
0365 
0366     return ret;
0367 }
0368 
0369 static struct counter_comp intel_qep_count_ext[] = {
0370     COUNTER_COMP_ENABLE(intel_qep_enable_read, intel_qep_enable_write),
0371     COUNTER_COMP_CEILING(intel_qep_ceiling_read, intel_qep_ceiling_write),
0372     COUNTER_COMP_PRESET_ENABLE(intel_qep_preset_enable_read,
0373                    intel_qep_preset_enable_write),
0374     COUNTER_COMP_COUNT_U64("spike_filter_ns",
0375                    intel_qep_spike_filter_ns_read,
0376                    intel_qep_spike_filter_ns_write),
0377 };
0378 
0379 static struct counter_count intel_qep_counter_count[] = {
0380     {
0381         .id = 0,
0382         .name = "Channel 1 Count",
0383         .functions_list = intel_qep_count_functions,
0384         .num_functions = ARRAY_SIZE(intel_qep_count_functions),
0385         .synapses = intel_qep_count_synapses,
0386         .num_synapses = ARRAY_SIZE(intel_qep_count_synapses),
0387         .ext = intel_qep_count_ext,
0388         .num_ext = ARRAY_SIZE(intel_qep_count_ext),
0389     },
0390 };
0391 
0392 static int intel_qep_probe(struct pci_dev *pci, const struct pci_device_id *id)
0393 {
0394     struct counter_device *counter;
0395     struct intel_qep *qep;
0396     struct device *dev = &pci->dev;
0397     void __iomem *regs;
0398     int ret;
0399 
0400     counter = devm_counter_alloc(dev, sizeof(*qep));
0401     if (!counter)
0402         return -ENOMEM;
0403     qep = counter_priv(counter);
0404 
0405     ret = pcim_enable_device(pci);
0406     if (ret)
0407         return ret;
0408 
0409     pci_set_master(pci);
0410 
0411     ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci));
0412     if (ret)
0413         return ret;
0414 
0415     regs = pcim_iomap_table(pci)[0];
0416     if (!regs)
0417         return -ENOMEM;
0418 
0419     qep->dev = dev;
0420     qep->regs = regs;
0421     mutex_init(&qep->lock);
0422 
0423     intel_qep_init(qep);
0424     pci_set_drvdata(pci, qep);
0425 
0426     counter->name = pci_name(pci);
0427     counter->parent = dev;
0428     counter->ops = &intel_qep_counter_ops;
0429     counter->counts = intel_qep_counter_count;
0430     counter->num_counts = ARRAY_SIZE(intel_qep_counter_count);
0431     counter->signals = intel_qep_signals;
0432     counter->num_signals = ARRAY_SIZE(intel_qep_signals);
0433     qep->enabled = false;
0434 
0435     pm_runtime_put(dev);
0436     pm_runtime_allow(dev);
0437 
0438     ret = devm_counter_add(&pci->dev, counter);
0439     if (ret < 0)
0440         return dev_err_probe(&pci->dev, ret, "Failed to add counter\n");
0441 
0442     return 0;
0443 }
0444 
0445 static void intel_qep_remove(struct pci_dev *pci)
0446 {
0447     struct intel_qep *qep = pci_get_drvdata(pci);
0448     struct device *dev = &pci->dev;
0449 
0450     pm_runtime_forbid(dev);
0451     if (!qep->enabled)
0452         pm_runtime_get(dev);
0453 
0454     intel_qep_writel(qep, INTEL_QEPCON, 0);
0455 }
0456 
0457 static int __maybe_unused intel_qep_suspend(struct device *dev)
0458 {
0459     struct pci_dev *pdev = to_pci_dev(dev);
0460     struct intel_qep *qep = pci_get_drvdata(pdev);
0461 
0462     qep->qepcon = intel_qep_readl(qep, INTEL_QEPCON);
0463     qep->qepflt = intel_qep_readl(qep, INTEL_QEPFLT);
0464     qep->qepmax = intel_qep_readl(qep, INTEL_QEPMAX);
0465 
0466     return 0;
0467 }
0468 
0469 static int __maybe_unused intel_qep_resume(struct device *dev)
0470 {
0471     struct pci_dev *pdev = to_pci_dev(dev);
0472     struct intel_qep *qep = pci_get_drvdata(pdev);
0473 
0474     /*
0475      * Make sure peripheral is disabled when restoring registers and
0476      * control register bits that are writable only when the peripheral
0477      * is disabled
0478      */
0479     intel_qep_writel(qep, INTEL_QEPCON, 0);
0480     intel_qep_readl(qep, INTEL_QEPCON);
0481 
0482     intel_qep_writel(qep, INTEL_QEPFLT, qep->qepflt);
0483     intel_qep_writel(qep, INTEL_QEPMAX, qep->qepmax);
0484     intel_qep_writel(qep, INTEL_QEPINT_MASK, INTEL_QEPINT_MASK_ALL);
0485 
0486     /* Restore all other control register bits except enable status */
0487     intel_qep_writel(qep, INTEL_QEPCON, qep->qepcon & ~INTEL_QEPCON_EN);
0488     intel_qep_readl(qep, INTEL_QEPCON);
0489 
0490     /* Restore enable status */
0491     intel_qep_writel(qep, INTEL_QEPCON, qep->qepcon);
0492 
0493     return 0;
0494 }
0495 
0496 static UNIVERSAL_DEV_PM_OPS(intel_qep_pm_ops,
0497                 intel_qep_suspend, intel_qep_resume, NULL);
0498 
0499 static const struct pci_device_id intel_qep_id_table[] = {
0500     /* EHL */
0501     { PCI_VDEVICE(INTEL, 0x4bc3), },
0502     { PCI_VDEVICE(INTEL, 0x4b81), },
0503     { PCI_VDEVICE(INTEL, 0x4b82), },
0504     { PCI_VDEVICE(INTEL, 0x4b83), },
0505     {  } /* Terminating Entry */
0506 };
0507 MODULE_DEVICE_TABLE(pci, intel_qep_id_table);
0508 
0509 static struct pci_driver intel_qep_driver = {
0510     .name = "intel-qep",
0511     .id_table = intel_qep_id_table,
0512     .probe = intel_qep_probe,
0513     .remove = intel_qep_remove,
0514     .driver = {
0515         .pm = &intel_qep_pm_ops,
0516     }
0517 };
0518 
0519 module_pci_driver(intel_qep_driver);
0520 
0521 MODULE_AUTHOR("Felipe Balbi (Intel)");
0522 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
0523 MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
0524 MODULE_LICENSE("GPL");
0525 MODULE_DESCRIPTION("Intel Quadrature Encoder Peripheral driver");