linux/arch/arm/mach-davinci/serial.c
<<
>>
Prefs
   1/*
   2 * TI DaVinci serial driver
   3 *
   4 * Copyright (C) 2006 Texas Instruments.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 *
  20 */
  21
  22#include <linux/kernel.h>
  23#include <linux/init.h>
  24#include <linux/serial_8250.h>
  25#include <linux/serial_reg.h>
  26#include <linux/platform_device.h>
  27#include <linux/delay.h>
  28#include <linux/clk.h>
  29#include <linux/io.h>
  30
  31#include <asm/irq.h>
  32#include <mach/hardware.h>
  33#include <mach/serial.h>
  34#include <mach/irqs.h>
  35#include <mach/cputype.h>
  36#include <mach/common.h>
  37
  38#include "clock.h"
  39
  40static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
  41                                           int offset)
  42{
  43        offset <<= up->regshift;
  44        return (unsigned int)__raw_readl(IO_ADDRESS(up->mapbase) + offset);
  45}
  46
  47static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
  48                                    int value)
  49{
  50        offset <<= p->regshift;
  51        __raw_writel(value, IO_ADDRESS(p->mapbase) + offset);
  52}
  53
  54static void __init davinci_serial_reset(struct plat_serial8250_port *p)
  55{
  56        unsigned int pwremu = 0;
  57
  58        serial_write_reg(p, UART_IER, 0);  /* disable all interrupts */
  59
  60        /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
  61        serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
  62        mdelay(10);
  63
  64        pwremu |= (0x3 << 13);
  65        pwremu |= 0x1;
  66        serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
  67
  68        if (cpu_is_davinci_dm646x())
  69                serial_write_reg(p, UART_DM646X_SCR,
  70                                 UART_DM646X_SCR_TX_WATERMARK);
  71}
  72
  73int __init davinci_serial_init(struct davinci_uart_config *info)
  74{
  75        int i;
  76        char name[16];
  77        struct clk *uart_clk;
  78        struct davinci_soc_info *soc_info = &davinci_soc_info;
  79        struct device *dev = &soc_info->serial_dev->dev;
  80        struct plat_serial8250_port *p = dev->platform_data;
  81
  82        /*
  83         * Make sure the serial ports are muxed on at this point.
  84         * You have to mux them off in device drivers later on if not needed.
  85         */
  86        for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++, p++) {
  87                if (!(info->enabled_uarts & (1 << i)))
  88                        continue;
  89
  90                sprintf(name, "uart%d", i);
  91                uart_clk = clk_get(dev, name);
  92                if (IS_ERR(uart_clk))
  93                        printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
  94                                        __func__, __LINE__, i);
  95                else {
  96                        clk_enable(uart_clk);
  97                        p->uartclk = clk_get_rate(uart_clk);
  98                        davinci_serial_reset(p);
  99                }
 100        }
 101
 102        return platform_device_register(soc_info->serial_dev);
 103}
 104