mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	dm: imx: serial: Support driver model in the MXC serial driver
Add driver model support with this driver. Boards which use this driver should define platform data in their board files. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							parent
							
								
									441d0cfff1
								
							
						
					
					
						commit
						a8ba569cba
					
				@ -5,37 +5,15 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <common.h>
 | 
					#include <common.h>
 | 
				
			||||||
 | 
					#include <dm.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <serial_mxc.h>
 | 
				
			||||||
#include <watchdog.h>
 | 
					#include <watchdog.h>
 | 
				
			||||||
#include <asm/arch/imx-regs.h>
 | 
					#include <asm/arch/imx-regs.h>
 | 
				
			||||||
#include <asm/arch/clock.h>
 | 
					#include <asm/arch/clock.h>
 | 
				
			||||||
#include <serial.h>
 | 
					#include <serial.h>
 | 
				
			||||||
#include <linux/compiler.h>
 | 
					#include <linux/compiler.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define __REG(x)     (*((volatile u32 *)(x)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef CONFIG_MXC_UART_BASE
 | 
					 | 
				
			||||||
#error "define CONFIG_MXC_UART_BASE to use the MXC UART driver"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define UART_PHYS	CONFIG_MXC_UART_BASE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Register definitions */
 | 
					 | 
				
			||||||
#define URXD  0x0  /* Receiver Register */
 | 
					 | 
				
			||||||
#define UTXD  0x40 /* Transmitter Register */
 | 
					 | 
				
			||||||
#define UCR1  0x80 /* Control Register 1 */
 | 
					 | 
				
			||||||
#define UCR2  0x84 /* Control Register 2 */
 | 
					 | 
				
			||||||
#define UCR3  0x88 /* Control Register 3 */
 | 
					 | 
				
			||||||
#define UCR4  0x8c /* Control Register 4 */
 | 
					 | 
				
			||||||
#define UFCR  0x90 /* FIFO Control Register */
 | 
					 | 
				
			||||||
#define USR1  0x94 /* Status Register 1 */
 | 
					 | 
				
			||||||
#define USR2  0x98 /* Status Register 2 */
 | 
					 | 
				
			||||||
#define UESC  0x9c /* Escape Character Register */
 | 
					 | 
				
			||||||
#define UTIM  0xa0 /* Escape Timer Register */
 | 
					 | 
				
			||||||
#define UBIR  0xa4 /* BRM Incremental Register */
 | 
					 | 
				
			||||||
#define UBMR  0xa8 /* BRM Modulator Register */
 | 
					 | 
				
			||||||
#define UBRC  0xac /* Baud Rate Count Register */
 | 
					 | 
				
			||||||
#define UTS   0xb4 /* UART Test Register (mx31) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* UART Control Register Bit Fields.*/
 | 
					/* UART Control Register Bit Fields.*/
 | 
				
			||||||
#define  URXD_CHARRDY    (1<<15)
 | 
					#define  URXD_CHARRDY    (1<<15)
 | 
				
			||||||
#define  URXD_ERR        (1<<14)
 | 
					#define  URXD_ERR        (1<<14)
 | 
				
			||||||
@ -128,6 +106,33 @@
 | 
				
			|||||||
#define  UTS_RXFULL	 (1<<3)	 /* RxFIFO full */
 | 
					#define  UTS_RXFULL	 (1<<3)	 /* RxFIFO full */
 | 
				
			||||||
#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
 | 
					#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_DM_SERIAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CONFIG_MXC_UART_BASE
 | 
				
			||||||
 | 
					#error "define CONFIG_MXC_UART_BASE to use the MXC UART driver"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define UART_PHYS	CONFIG_MXC_UART_BASE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define __REG(x)     (*((volatile u32 *)(x)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Register definitions */
 | 
				
			||||||
 | 
					#define URXD  0x0  /* Receiver Register */
 | 
				
			||||||
 | 
					#define UTXD  0x40 /* Transmitter Register */
 | 
				
			||||||
 | 
					#define UCR1  0x80 /* Control Register 1 */
 | 
				
			||||||
 | 
					#define UCR2  0x84 /* Control Register 2 */
 | 
				
			||||||
 | 
					#define UCR3  0x88 /* Control Register 3 */
 | 
				
			||||||
 | 
					#define UCR4  0x8c /* Control Register 4 */
 | 
				
			||||||
 | 
					#define UFCR  0x90 /* FIFO Control Register */
 | 
				
			||||||
 | 
					#define USR1  0x94 /* Status Register 1 */
 | 
				
			||||||
 | 
					#define USR2  0x98 /* Status Register 2 */
 | 
				
			||||||
 | 
					#define UESC  0x9c /* Escape Character Register */
 | 
				
			||||||
 | 
					#define UTIM  0xa0 /* Escape Timer Register */
 | 
				
			||||||
 | 
					#define UBIR  0xa4 /* BRM Incremental Register */
 | 
				
			||||||
 | 
					#define UBMR  0xa8 /* BRM Modulator Register */
 | 
				
			||||||
 | 
					#define UBRC  0xac /* Baud Rate Count Register */
 | 
				
			||||||
 | 
					#define UTS   0xb4 /* UART Test Register (mx31) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DECLARE_GLOBAL_DATA_PTR;
 | 
					DECLARE_GLOBAL_DATA_PTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void mxc_serial_setbrg(void)
 | 
					static void mxc_serial_setbrg(void)
 | 
				
			||||||
@ -222,3 +227,118 @@ __weak struct serial_device *default_serial_console(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	return &mxc_serial_drv;
 | 
						return &mxc_serial_drv;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_SERIAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mxc_uart {
 | 
				
			||||||
 | 
						u32 rxd;
 | 
				
			||||||
 | 
						u32 spare0[15];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 txd;
 | 
				
			||||||
 | 
						u32 spare1[15];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 cr1;
 | 
				
			||||||
 | 
						u32 cr2;
 | 
				
			||||||
 | 
						u32 cr3;
 | 
				
			||||||
 | 
						u32 cr4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 fcr;
 | 
				
			||||||
 | 
						u32 sr1;
 | 
				
			||||||
 | 
						u32 sr2;
 | 
				
			||||||
 | 
						u32 esc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 tim;
 | 
				
			||||||
 | 
						u32 bir;
 | 
				
			||||||
 | 
						u32 bmr;
 | 
				
			||||||
 | 
						u32 brc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 onems;
 | 
				
			||||||
 | 
						u32 ts;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mxc_serial_setbrg(struct udevice *dev, int baudrate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mxc_serial_platdata *plat = dev->platdata;
 | 
				
			||||||
 | 
						struct mxc_uart *const uart = plat->reg;
 | 
				
			||||||
 | 
						u32 clk = imx_get_uartclk();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writel(4 << 7, &uart->fcr); /* divide input clock by 2 */
 | 
				
			||||||
 | 
						writel(0xf, &uart->bir);
 | 
				
			||||||
 | 
						writel(clk / (2 * baudrate), &uart->bmr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writel(UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST,
 | 
				
			||||||
 | 
						       &uart->cr2);
 | 
				
			||||||
 | 
						writel(UCR1_UARTEN, &uart->cr1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mxc_serial_probe(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mxc_serial_platdata *plat = dev->platdata;
 | 
				
			||||||
 | 
						struct mxc_uart *const uart = plat->reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writel(0, &uart->cr1);
 | 
				
			||||||
 | 
						writel(0, &uart->cr2);
 | 
				
			||||||
 | 
						while (!(readl(&uart->cr2) & UCR2_SRST));
 | 
				
			||||||
 | 
						writel(0x704 | UCR3_ADNIMP, &uart->cr3);
 | 
				
			||||||
 | 
						writel(0x8000, &uart->cr4);
 | 
				
			||||||
 | 
						writel(0x2b, &uart->esc);
 | 
				
			||||||
 | 
						writel(0, &uart->tim);
 | 
				
			||||||
 | 
						writel(0, &uart->ts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mxc_serial_getc(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mxc_serial_platdata *plat = dev->platdata;
 | 
				
			||||||
 | 
						struct mxc_uart *const uart = plat->reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (readl(&uart->ts) & UTS_RXEMPTY)
 | 
				
			||||||
 | 
							return -EAGAIN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return readl(&uart->rxd) & URXD_RX_DATA;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mxc_serial_putc(struct udevice *dev, const char ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mxc_serial_platdata *plat = dev->platdata;
 | 
				
			||||||
 | 
						struct mxc_uart *const uart = plat->reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(readl(&uart->ts) & UTS_TXEMPTY))
 | 
				
			||||||
 | 
							return -EAGAIN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writel(ch, &uart->txd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mxc_serial_pending(struct udevice *dev, bool input)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mxc_serial_platdata *plat = dev->platdata;
 | 
				
			||||||
 | 
						struct mxc_uart *const uart = plat->reg;
 | 
				
			||||||
 | 
						uint32_t sr2 = readl(&uart->sr2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (input)
 | 
				
			||||||
 | 
							return sr2 & USR2_RDR ? 1 : 0;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return sr2 & USR2_TXDC ? 0 : 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct dm_serial_ops mxc_serial_ops = {
 | 
				
			||||||
 | 
						.putc = mxc_serial_putc,
 | 
				
			||||||
 | 
						.pending = mxc_serial_pending,
 | 
				
			||||||
 | 
						.getc = mxc_serial_getc,
 | 
				
			||||||
 | 
						.setbrg = mxc_serial_setbrg,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					U_BOOT_DRIVER(serial_mxc) = {
 | 
				
			||||||
 | 
						.name	= "serial_mxc",
 | 
				
			||||||
 | 
						.id	= UCLASS_SERIAL,
 | 
				
			||||||
 | 
						.probe = mxc_serial_probe,
 | 
				
			||||||
 | 
						.ops	= &mxc_serial_ops,
 | 
				
			||||||
 | 
						.flags = DM_FLAG_PRE_RELOC,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								include/serial_mxc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								include/serial_mxc.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2014 Google, Inc
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier:	GPL-2.0+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __serial_mxc_h
 | 
				
			||||||
 | 
					#define __serial_mxc_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Information about a serial port */
 | 
				
			||||||
 | 
					struct mxc_serial_platdata {
 | 
				
			||||||
 | 
						struct mxc_uart *reg;  /* address of registers in physical memory */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user