Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * TI DaVinci serial driver
0004  *
0005  * Copyright (C) 2006 Texas Instruments.
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/init.h>
0010 #include <linux/serial_8250.h>
0011 #include <linux/serial_reg.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/delay.h>
0014 #include <linux/clk.h>
0015 #include <linux/io.h>
0016 
0017 #include "serial.h"
0018 #include "cputype.h"
0019 
0020 static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
0021                     int value)
0022 {
0023     offset <<= p->regshift;
0024 
0025     WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
0026 
0027     __raw_writel(value, p->membase + offset);
0028 }
0029 
0030 static void __init davinci_serial_reset(struct plat_serial8250_port *p)
0031 {
0032     unsigned int pwremu = 0;
0033 
0034     serial_write_reg(p, UART_IER, 0);  /* disable all interrupts */
0035 
0036     /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
0037     serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
0038     mdelay(10);
0039 
0040     pwremu |= (0x3 << 13);
0041     pwremu |= 0x1;
0042     serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
0043 
0044     if (cpu_is_davinci_dm646x())
0045         serial_write_reg(p, UART_DM646X_SCR,
0046                  UART_DM646X_SCR_TX_WATERMARK);
0047 }
0048 
0049 int __init davinci_serial_init(struct platform_device *serial_dev)
0050 {
0051     int i, ret = 0;
0052     struct device *dev;
0053     struct plat_serial8250_port *p;
0054     struct clk *clk;
0055 
0056     /*
0057      * Make sure the serial ports are muxed on at this point.
0058      * You have to mux them off in device drivers later on if not needed.
0059      */
0060     for (i = 0; serial_dev[i].dev.platform_data != NULL; i++) {
0061         dev = &serial_dev[i].dev;
0062         p = dev->platform_data;
0063 
0064         ret = platform_device_register(&serial_dev[i]);
0065         if (ret)
0066             continue;
0067 
0068         clk = clk_get(dev, NULL);
0069         if (IS_ERR(clk)) {
0070             pr_err("%s:%d: failed to get UART%d clock\n",
0071                    __func__, __LINE__, i);
0072             continue;
0073         }
0074 
0075         clk_prepare_enable(clk);
0076 
0077         p->uartclk = clk_get_rate(clk);
0078 
0079         if (!p->membase && p->mapbase) {
0080             p->membase = ioremap(p->mapbase, SZ_4K);
0081 
0082             if (p->membase)
0083                 p->flags &= ~UPF_IOREMAP;
0084             else
0085                 pr_err("uart regs ioremap failed\n");
0086         }
0087 
0088         if (p->membase && p->type != PORT_AR7)
0089             davinci_serial_reset(p);
0090     }
0091     return ret;
0092 }