Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/console.h>
0008 #include <linux/io.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/platform_device.h>
0012 
0013 #include "8250.h"
0014 
0015 /*
0016  * This hardware is similar to 8250, but its register map is a bit different:
0017  *   - MMIO32 (regshift = 2)
0018  *   - FCR is not at 2, but 3
0019  *   - LCR and MCR are not at 3 and 4, they share 4
0020  *   - No SCR (Instead, CHAR can be used as a scratch register)
0021  *   - Divisor latch at 9, no divisor latch access bit
0022  */
0023 
0024 #define UNIPHIER_UART_REGSHIFT      2
0025 
0026 /* bit[15:8] = CHAR, bit[7:0] = FCR */
0027 #define UNIPHIER_UART_CHAR_FCR      (3 << (UNIPHIER_UART_REGSHIFT))
0028 /* bit[15:8] = LCR, bit[7:0] = MCR */
0029 #define UNIPHIER_UART_LCR_MCR       (4 << (UNIPHIER_UART_REGSHIFT))
0030 /* Divisor Latch Register */
0031 #define UNIPHIER_UART_DLR       (9 << (UNIPHIER_UART_REGSHIFT))
0032 
0033 struct uniphier8250_priv {
0034     int line;
0035     struct clk *clk;
0036     spinlock_t atomic_write_lock;
0037 };
0038 
0039 #ifdef CONFIG_SERIAL_8250_CONSOLE
0040 static int __init uniphier_early_console_setup(struct earlycon_device *device,
0041                            const char *options)
0042 {
0043     if (!device->port.membase)
0044         return -ENODEV;
0045 
0046     /* This hardware always expects MMIO32 register interface. */
0047     device->port.iotype = UPIO_MEM32;
0048     device->port.regshift = UNIPHIER_UART_REGSHIFT;
0049 
0050     /*
0051      * Do not touch the divisor register in early_serial8250_setup();
0052      * we assume it has been initialized by a boot loader.
0053      */
0054     device->baud = 0;
0055 
0056     return early_serial8250_setup(device, options);
0057 }
0058 OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart",
0059             uniphier_early_console_setup);
0060 #endif
0061 
0062 /*
0063  * The register map is slightly different from that of 8250.
0064  * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR.
0065  */
0066 static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
0067 {
0068     unsigned int valshift = 0;
0069 
0070     switch (offset) {
0071     case UART_SCR:
0072         /* No SCR for this hardware.  Use CHAR as a scratch register */
0073         valshift = 8;
0074         offset = UNIPHIER_UART_CHAR_FCR;
0075         break;
0076     case UART_LCR:
0077         valshift = 8;
0078         fallthrough;
0079     case UART_MCR:
0080         offset = UNIPHIER_UART_LCR_MCR;
0081         break;
0082     default:
0083         offset <<= UNIPHIER_UART_REGSHIFT;
0084         break;
0085     }
0086 
0087     /*
0088      * The return value must be masked with 0xff because some registers
0089      * share the same offset that must be accessed by 32-bit write/read.
0090      * 8 or 16 bit access to this hardware result in unexpected behavior.
0091      */
0092     return (readl(p->membase + offset) >> valshift) & 0xff;
0093 }
0094 
0095 static void uniphier_serial_out(struct uart_port *p, int offset, int value)
0096 {
0097     unsigned int valshift = 0;
0098     bool normal = false;
0099 
0100     switch (offset) {
0101     case UART_SCR:
0102         /* No SCR for this hardware.  Use CHAR as a scratch register */
0103         valshift = 8;
0104         fallthrough;
0105     case UART_FCR:
0106         offset = UNIPHIER_UART_CHAR_FCR;
0107         break;
0108     case UART_LCR:
0109         valshift = 8;
0110         /* Divisor latch access bit does not exist. */
0111         value &= ~UART_LCR_DLAB;
0112         fallthrough;
0113     case UART_MCR:
0114         offset = UNIPHIER_UART_LCR_MCR;
0115         break;
0116     default:
0117         offset <<= UNIPHIER_UART_REGSHIFT;
0118         normal = true;
0119         break;
0120     }
0121 
0122     if (normal) {
0123         writel(value, p->membase + offset);
0124     } else {
0125         /*
0126          * Special case: two registers share the same address that
0127          * must be 32-bit accessed.  As this is not longer atomic safe,
0128          * take a lock just in case.
0129          */
0130         struct uniphier8250_priv *priv = p->private_data;
0131         unsigned long flags;
0132         u32 tmp;
0133 
0134         spin_lock_irqsave(&priv->atomic_write_lock, flags);
0135         tmp = readl(p->membase + offset);
0136         tmp &= ~(0xff << valshift);
0137         tmp |= value << valshift;
0138         writel(tmp, p->membase + offset);
0139         spin_unlock_irqrestore(&priv->atomic_write_lock, flags);
0140     }
0141 }
0142 
0143 /*
0144  * This hardware does not have the divisor latch access bit.
0145  * The divisor latch register exists at different address.
0146  * Override dl_read/write callbacks.
0147  */
0148 static int uniphier_serial_dl_read(struct uart_8250_port *up)
0149 {
0150     return readl(up->port.membase + UNIPHIER_UART_DLR);
0151 }
0152 
0153 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
0154 {
0155     writel(value, up->port.membase + UNIPHIER_UART_DLR);
0156 }
0157 
0158 static int uniphier_uart_probe(struct platform_device *pdev)
0159 {
0160     struct device *dev = &pdev->dev;
0161     struct uart_8250_port up;
0162     struct uniphier8250_priv *priv;
0163     struct resource *regs;
0164     void __iomem *membase;
0165     int irq;
0166     int ret;
0167 
0168     regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0169     if (!regs) {
0170         dev_err(dev, "failed to get memory resource\n");
0171         return -EINVAL;
0172     }
0173 
0174     membase = devm_ioremap(dev, regs->start, resource_size(regs));
0175     if (!membase)
0176         return -ENOMEM;
0177 
0178     irq = platform_get_irq(pdev, 0);
0179     if (irq < 0)
0180         return irq;
0181 
0182     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0183     if (!priv)
0184         return -ENOMEM;
0185 
0186     memset(&up, 0, sizeof(up));
0187 
0188     ret = of_alias_get_id(dev->of_node, "serial");
0189     if (ret < 0) {
0190         dev_err(dev, "failed to get alias id\n");
0191         return ret;
0192     }
0193     up.port.line = ret;
0194 
0195     priv->clk = devm_clk_get(dev, NULL);
0196     if (IS_ERR(priv->clk)) {
0197         dev_err(dev, "failed to get clock\n");
0198         return PTR_ERR(priv->clk);
0199     }
0200 
0201     ret = clk_prepare_enable(priv->clk);
0202     if (ret)
0203         return ret;
0204 
0205     up.port.uartclk = clk_get_rate(priv->clk);
0206 
0207     spin_lock_init(&priv->atomic_write_lock);
0208 
0209     up.port.dev = dev;
0210     up.port.private_data = priv;
0211     up.port.mapbase = regs->start;
0212     up.port.mapsize = resource_size(regs);
0213     up.port.membase = membase;
0214     up.port.irq = irq;
0215 
0216     up.port.type = PORT_16550A;
0217     up.port.iotype = UPIO_MEM32;
0218     up.port.fifosize = 64;
0219     up.port.regshift = UNIPHIER_UART_REGSHIFT;
0220     up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE;
0221     up.capabilities = UART_CAP_FIFO;
0222 
0223     if (of_property_read_bool(dev->of_node, "auto-flow-control"))
0224         up.capabilities |= UART_CAP_AFE;
0225 
0226     up.port.serial_in = uniphier_serial_in;
0227     up.port.serial_out = uniphier_serial_out;
0228     up.dl_read = uniphier_serial_dl_read;
0229     up.dl_write = uniphier_serial_dl_write;
0230 
0231     ret = serial8250_register_8250_port(&up);
0232     if (ret < 0) {
0233         dev_err(dev, "failed to register 8250 port\n");
0234         clk_disable_unprepare(priv->clk);
0235         return ret;
0236     }
0237     priv->line = ret;
0238 
0239     platform_set_drvdata(pdev, priv);
0240 
0241     return 0;
0242 }
0243 
0244 static int uniphier_uart_remove(struct platform_device *pdev)
0245 {
0246     struct uniphier8250_priv *priv = platform_get_drvdata(pdev);
0247 
0248     serial8250_unregister_port(priv->line);
0249     clk_disable_unprepare(priv->clk);
0250 
0251     return 0;
0252 }
0253 
0254 static int __maybe_unused uniphier_uart_suspend(struct device *dev)
0255 {
0256     struct uniphier8250_priv *priv = dev_get_drvdata(dev);
0257     struct uart_8250_port *up = serial8250_get_port(priv->line);
0258 
0259     serial8250_suspend_port(priv->line);
0260 
0261     if (!uart_console(&up->port) || console_suspend_enabled)
0262         clk_disable_unprepare(priv->clk);
0263 
0264     return 0;
0265 }
0266 
0267 static int __maybe_unused uniphier_uart_resume(struct device *dev)
0268 {
0269     struct uniphier8250_priv *priv = dev_get_drvdata(dev);
0270     struct uart_8250_port *up = serial8250_get_port(priv->line);
0271     int ret;
0272 
0273     if (!uart_console(&up->port) || console_suspend_enabled) {
0274         ret = clk_prepare_enable(priv->clk);
0275         if (ret)
0276             return ret;
0277     }
0278 
0279     serial8250_resume_port(priv->line);
0280 
0281     return 0;
0282 }
0283 
0284 static const struct dev_pm_ops uniphier_uart_pm_ops = {
0285     SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume)
0286 };
0287 
0288 static const struct of_device_id uniphier_uart_match[] = {
0289     { .compatible = "socionext,uniphier-uart" },
0290     { /* sentinel */ }
0291 };
0292 MODULE_DEVICE_TABLE(of, uniphier_uart_match);
0293 
0294 static struct platform_driver uniphier_uart_platform_driver = {
0295     .probe      = uniphier_uart_probe,
0296     .remove     = uniphier_uart_remove,
0297     .driver = {
0298         .name   = "uniphier-uart",
0299         .of_match_table = uniphier_uart_match,
0300         .pm = &uniphier_uart_pm_ops,
0301     },
0302 };
0303 module_platform_driver(uniphier_uart_platform_driver);
0304 
0305 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
0306 MODULE_DESCRIPTION("UniPhier UART driver");
0307 MODULE_LICENSE("GPL");