linux/arch/arm/mach-davinci/serial.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * TI DaVinci serial driver
   4 *
   5 * Copyright (C) 2006 Texas Instruments.
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/init.h>
  10#include <linux/serial_8250.h>
  11#include <linux/serial_reg.h>
  12#include <linux/platform_device.h>
  13#include <linux/delay.h>
  14#include <linux/clk.h>
  15#include <linux/io.h>
  16
  17#include <mach/serial.h>
  18#include <mach/cputype.h>
  19
  20static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
  21                                    int value)
  22{
  23        offset <<= p->regshift;
  24
  25        WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
  26
  27        __raw_writel(value, p->membase + offset);
  28}
  29
  30static void __init davinci_serial_reset(struct plat_serial8250_port *p)
  31{
  32        unsigned int pwremu = 0;
  33
  34        serial_write_reg(p, UART_IER, 0);  /* disable all interrupts */
  35
  36        /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
  37        serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
  38        mdelay(10);
  39
  40        pwremu |= (0x3 << 13);
  41        pwremu |= 0x1;
  42        serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
  43
  44        if (cpu_is_davinci_dm646x())
  45                serial_write_reg(p, UART_DM646X_SCR,
  46                                 UART_DM646X_SCR_TX_WATERMARK);
  47}
  48
  49int __init davinci_serial_init(struct platform_device *serial_dev)
  50{
  51        int i, ret = 0;
  52        struct device *dev;
  53        struct plat_serial8250_port *p;
  54        struct clk *clk;
  55
  56        /*
  57         * Make sure the serial ports are muxed on at this point.
  58         * You have to mux them off in device drivers later on if not needed.
  59         */
  60        for (i = 0; serial_dev[i].dev.platform_data != NULL; i++) {
  61                dev = &serial_dev[i].dev;
  62                p = dev->platform_data;
  63
  64                ret = platform_device_register(&serial_dev[i]);
  65                if (ret)
  66                        continue;
  67
  68                clk = clk_get(dev, NULL);
  69                if (IS_ERR(clk)) {
  70                        pr_err("%s:%d: failed to get UART%d clock\n",
  71                               __func__, __LINE__, i);
  72                        continue;
  73                }
  74
  75                clk_prepare_enable(clk);
  76
  77                p->uartclk = clk_get_rate(clk);
  78
  79                if (!p->membase && p->mapbase) {
  80                        p->membase = ioremap(p->mapbase, SZ_4K);
  81
  82                        if (p->membase)
  83                                p->flags &= ~UPF_IOREMAP;
  84                        else
  85                                pr_err("uart regs ioremap failed\n");
  86                }
  87
  88                if (p->membase && p->type != PORT_AR7)
  89                        davinci_serial_reset(p);
  90        }
  91        return ret;
  92}
  93