serial.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * arch/arm/mach-omap2/serial.c
  3. *
  4. * OMAP2 serial support.
  5. *
  6. * Copyright (C) 2005-2008 Nokia Corporation
  7. * Author: Paul Mundt <paul.mundt@nokia.com>
  8. *
  9. * Based off of arch/arm/mach-omap/omap1/serial.c
  10. *
  11. * This file is subject to the terms and conditions of the GNU General Public
  12. * License. See the file "COPYING" in the main directory of this archive
  13. * for more details.
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/init.h>
  17. #include <linux/serial_8250.h>
  18. #include <linux/serial_reg.h>
  19. #include <linux/clk.h>
  20. #include <linux/io.h>
  21. #include <mach/common.h>
  22. #include <mach/board.h>
  23. static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
  24. static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
  25. static struct plat_serial8250_port serial_platform_data[] = {
  26. {
  27. .membase = IO_ADDRESS(OMAP_UART1_BASE),
  28. .mapbase = OMAP_UART1_BASE,
  29. .irq = 72,
  30. .flags = UPF_BOOT_AUTOCONF,
  31. .iotype = UPIO_MEM,
  32. .regshift = 2,
  33. .uartclk = OMAP24XX_BASE_BAUD * 16,
  34. }, {
  35. .membase = IO_ADDRESS(OMAP_UART2_BASE),
  36. .mapbase = OMAP_UART2_BASE,
  37. .irq = 73,
  38. .flags = UPF_BOOT_AUTOCONF,
  39. .iotype = UPIO_MEM,
  40. .regshift = 2,
  41. .uartclk = OMAP24XX_BASE_BAUD * 16,
  42. }, {
  43. .membase = IO_ADDRESS(OMAP_UART3_BASE),
  44. .mapbase = OMAP_UART3_BASE,
  45. .irq = 74,
  46. .flags = UPF_BOOT_AUTOCONF,
  47. .iotype = UPIO_MEM,
  48. .regshift = 2,
  49. .uartclk = OMAP24XX_BASE_BAUD * 16,
  50. }, {
  51. .flags = 0
  52. }
  53. };
  54. static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
  55. int offset)
  56. {
  57. offset <<= up->regshift;
  58. return (unsigned int)__raw_readb(up->membase + offset);
  59. }
  60. static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
  61. int value)
  62. {
  63. offset <<= p->regshift;
  64. __raw_writeb(value, p->membase + offset);
  65. }
  66. /*
  67. * Internal UARTs need to be initialized for the 8250 autoconfig to work
  68. * properly. Note that the TX watermark initialization may not be needed
  69. * once the 8250.c watermark handling code is merged.
  70. */
  71. static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
  72. {
  73. serial_write_reg(p, UART_OMAP_MDR1, 0x07);
  74. serial_write_reg(p, UART_OMAP_SCR, 0x08);
  75. serial_write_reg(p, UART_OMAP_MDR1, 0x00);
  76. serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
  77. }
  78. void omap_serial_enable_clocks(int enable)
  79. {
  80. int i;
  81. for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
  82. if (uart_ick[i] && uart_fck[i]) {
  83. if (enable) {
  84. clk_enable(uart_ick[i]);
  85. clk_enable(uart_fck[i]);
  86. } else {
  87. clk_disable(uart_ick[i]);
  88. clk_disable(uart_fck[i]);
  89. }
  90. }
  91. }
  92. }
  93. void __init omap_serial_init(void)
  94. {
  95. int i;
  96. const struct omap_uart_config *info;
  97. char name[16];
  98. /*
  99. * Make sure the serial ports are muxed on at this point.
  100. * You have to mux them off in device drivers later on
  101. * if not needed.
  102. */
  103. info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
  104. if (info == NULL)
  105. return;
  106. for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
  107. struct plat_serial8250_port *p = serial_platform_data + i;
  108. if (!(info->enabled_uarts & (1 << i))) {
  109. p->membase = NULL;
  110. p->mapbase = 0;
  111. continue;
  112. }
  113. sprintf(name, "uart%d_ick", i+1);
  114. uart_ick[i] = clk_get(NULL, name);
  115. if (IS_ERR(uart_ick[i])) {
  116. printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
  117. uart_ick[i] = NULL;
  118. } else
  119. clk_enable(uart_ick[i]);
  120. sprintf(name, "uart%d_fck", i+1);
  121. uart_fck[i] = clk_get(NULL, name);
  122. if (IS_ERR(uart_fck[i])) {
  123. printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
  124. uart_fck[i] = NULL;
  125. } else
  126. clk_enable(uart_fck[i]);
  127. omap_serial_reset(p);
  128. }
  129. }
  130. static struct platform_device serial_device = {
  131. .name = "serial8250",
  132. .id = PLAT8250_DEV_PLATFORM,
  133. .dev = {
  134. .platform_data = serial_platform_data,
  135. },
  136. };
  137. static int __init omap_init(void)
  138. {
  139. return platform_device_register(&serial_device);
  140. }
  141. arch_initcall(omap_init);