Blame view

drivers/serial/serial_uniphier.c 3.37 KB
7f368553f   Masahiro Yamada   serial: add UniPh...
1
  /*
4e3d84066   Masahiro Yamada   ARM: uniphier: us...
2
3
4
   * Copyright (C) 2012-2015 Panasonic Corporation
   * Copyright (C) 2015-2016 Socionext Inc.
   *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
7f368553f   Masahiro Yamada   serial: add UniPh...
5
   *
7f368553f   Masahiro Yamada   serial: add UniPh...
6
7
   * SPDX-License-Identifier:	GPL-2.0+
   */
4af0d7e87   Simon Glass   dm: Fix up inclus...
8
  #include <common.h>
9d922450a   Simon Glass   dm: Use dm.h head...
9
  #include <dm.h>
f6e7f07c1   Masahiro Yamada   ARM: UniPhier: re...
10
  #include <linux/io.h>
325b708a6   Masahiro Yamada   serial: UniPhier:...
11
  #include <linux/serial_reg.h>
b37a1ccea   Masahiro Yamada   serial: uniphier:...
12
  #include <linux/sizes.h>
1221ce459   Masahiro Yamada   treewide: replace...
13
  #include <linux/errno.h>
7f368553f   Masahiro Yamada   serial: add UniPh...
14
  #include <serial.h>
625177d27   Masahiro Yamada   serial: UniPhier:...
15
  #include <fdtdec.h>
7f368553f   Masahiro Yamada   serial: add UniPh...
16

7f368553f   Masahiro Yamada   serial: add UniPh...
17
18
19
20
  /*
   * Note: Register map is slightly different from that of 16550.
   */
  struct uniphier_serial {
d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
21
22
23
24
25
26
27
28
29
30
31
32
33
  	u32 rx;			/* In:  Receive buffer */
  #define tx rx			/* Out: Transmit buffer */
  	u32 ier;		/* Interrupt Enable Register */
  	u32 iir;		/* In: Interrupt ID Register */
  	u32 char_fcr;		/* Charactor / FIFO Control Register */
  	u32 lcr_mcr;		/* Line/Modem Control Register */
  #define LCR_SHIFT	8
  #define LCR_MASK	(0xff << (LCR_SHIFT))
  	u32 lsr;		/* In: Line Status Register */
  	u32 msr;		/* In: Modem Status Register */
  	u32 __rsv0;
  	u32 __rsv1;
  	u32 dlr;		/* Divisor Latch Register */
7f368553f   Masahiro Yamada   serial: add UniPh...
34
  };
d064cbfff   Masahiro Yamada   dm: serial: use D...
35
36
  struct uniphier_serial_private_data {
  	struct uniphier_serial __iomem *membase;
6d99cfaee   Masahiro Yamada   serial: uniphier:...
37
  	unsigned int uartclk;
d064cbfff   Masahiro Yamada   dm: serial: use D...
38
39
40
41
  };
  
  #define uniphier_serial_port(dev)	\
  	((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase
7f368553f   Masahiro Yamada   serial: add UniPh...
42

d9bc8fd1c   Masahiro Yamada   serial: UniPhier:...
43
  static int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
7f368553f   Masahiro Yamada   serial: add UniPh...
44
  {
6d99cfaee   Masahiro Yamada   serial: uniphier:...
45
  	struct uniphier_serial_private_data *priv = dev_get_priv(dev);
d064cbfff   Masahiro Yamada   dm: serial: use D...
46
  	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
7f368553f   Masahiro Yamada   serial: add UniPh...
47
48
  	const unsigned int mode_x_div = 16;
  	unsigned int divisor;
7f368553f   Masahiro Yamada   serial: add UniPh...
49

6d99cfaee   Masahiro Yamada   serial: uniphier:...
50
  	divisor = DIV_ROUND_CLOSEST(priv->uartclk, mode_x_div * baudrate);
7f368553f   Masahiro Yamada   serial: add UniPh...
51

d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
52
  	writel(divisor, &port->dlr);
7f368553f   Masahiro Yamada   serial: add UniPh...
53

d064cbfff   Masahiro Yamada   dm: serial: use D...
54
  	return 0;
7f368553f   Masahiro Yamada   serial: add UniPh...
55
  }
d064cbfff   Masahiro Yamada   dm: serial: use D...
56
  static int uniphier_serial_getc(struct udevice *dev)
7f368553f   Masahiro Yamada   serial: add UniPh...
57
  {
d064cbfff   Masahiro Yamada   dm: serial: use D...
58
  	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
7f368553f   Masahiro Yamada   serial: add UniPh...
59

d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
60
  	if (!(readl(&port->lsr) & UART_LSR_DR))
d064cbfff   Masahiro Yamada   dm: serial: use D...
61
  		return -EAGAIN;
7f368553f   Masahiro Yamada   serial: add UniPh...
62

d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
63
  	return readl(&port->rx);
7f368553f   Masahiro Yamada   serial: add UniPh...
64
  }
d064cbfff   Masahiro Yamada   dm: serial: use D...
65
  static int uniphier_serial_putc(struct udevice *dev, const char c)
7f368553f   Masahiro Yamada   serial: add UniPh...
66
  {
d064cbfff   Masahiro Yamada   dm: serial: use D...
67
  	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
7f368553f   Masahiro Yamada   serial: add UniPh...
68

d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
69
  	if (!(readl(&port->lsr) & UART_LSR_THRE))
d064cbfff   Masahiro Yamada   dm: serial: use D...
70
  		return -EAGAIN;
7f368553f   Masahiro Yamada   serial: add UniPh...
71

d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
72
  	writel(c, &port->tx);
d064cbfff   Masahiro Yamada   dm: serial: use D...
73
74
  
  	return 0;
7f368553f   Masahiro Yamada   serial: add UniPh...
75
  }
bb72148b2   Masahiro Yamada   serial: UniPhier:...
76
77
78
79
80
  static int uniphier_serial_pending(struct udevice *dev, bool input)
  {
  	struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
  
  	if (input)
d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
81
  		return readl(&port->lsr) & UART_LSR_DR;
bb72148b2   Masahiro Yamada   serial: UniPhier:...
82
  	else
d0c47b3ef   Masahiro Yamada   serial: UniPhier:...
83
  		return !(readl(&port->lsr) & UART_LSR_THRE);
bb72148b2   Masahiro Yamada   serial: UniPhier:...
84
  }
d9bc8fd1c   Masahiro Yamada   serial: UniPhier:...
85
  static int uniphier_serial_probe(struct udevice *dev)
d064cbfff   Masahiro Yamada   dm: serial: use D...
86
  {
6d99cfaee   Masahiro Yamada   serial: uniphier:...
87
  	DECLARE_GLOBAL_DATA_PTR;
d064cbfff   Masahiro Yamada   dm: serial: use D...
88
  	struct uniphier_serial_private_data *priv = dev_get_priv(dev);
099cf77c1   Masahiro Yamada   serial: UniPhier:...
89
  	struct uniphier_serial __iomem *port;
6d99cfaee   Masahiro Yamada   serial: uniphier:...
90
  	fdt_addr_t base;
6d99cfaee   Masahiro Yamada   serial: uniphier:...
91
  	u32 tmp;
7f368553f   Masahiro Yamada   serial: add UniPh...
92

a821c4af7   Simon Glass   dm: Rename dev_ad...
93
  	base = devfdt_get_addr(dev);
b37a1ccea   Masahiro Yamada   serial: uniphier:...
94
95
  	if (base == FDT_ADDR_T_NONE)
  		return -EINVAL;
6d99cfaee   Masahiro Yamada   serial: uniphier:...
96

4e3d84066   Masahiro Yamada   ARM: uniphier: us...
97
  	port = devm_ioremap(dev, base, SZ_64);
099cf77c1   Masahiro Yamada   serial: UniPhier:...
98
  	if (!port)
d064cbfff   Masahiro Yamada   dm: serial: use D...
99
  		return -ENOMEM;
7f368553f   Masahiro Yamada   serial: add UniPh...
100

099cf77c1   Masahiro Yamada   serial: UniPhier:...
101
  	priv->membase = port;
e160f7d43   Simon Glass   dm: core: Replace...
102
  	priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
6d99cfaee   Masahiro Yamada   serial: uniphier:...
103
  				       "clock-frequency", 0);
099cf77c1   Masahiro Yamada   serial: UniPhier:...
104
105
106
107
  	tmp = readl(&port->lcr_mcr);
  	tmp &= ~LCR_MASK;
  	tmp |= UART_LCR_WLEN8 << LCR_SHIFT;
  	writel(tmp, &port->lcr_mcr);
d064cbfff   Masahiro Yamada   dm: serial: use D...
108
109
  	return 0;
  }
625177d27   Masahiro Yamada   serial: UniPhier:...
110
  static const struct udevice_id uniphier_uart_of_match[] = {
6462cdedc   Masahiro Yamada   ARM: UniPhier: ad...
111
112
  	{ .compatible = "socionext,uniphier-uart" },
  	{ /* sentinel */ }
d064cbfff   Masahiro Yamada   dm: serial: use D...
113
  };
d064cbfff   Masahiro Yamada   dm: serial: use D...
114
115
116
117
  static const struct dm_serial_ops uniphier_serial_ops = {
  	.setbrg = uniphier_serial_setbrg,
  	.getc = uniphier_serial_getc,
  	.putc = uniphier_serial_putc,
bb72148b2   Masahiro Yamada   serial: UniPhier:...
118
  	.pending = uniphier_serial_pending,
d064cbfff   Masahiro Yamada   dm: serial: use D...
119
120
121
  };
  
  U_BOOT_DRIVER(uniphier_serial) = {
6d99cfaee   Masahiro Yamada   serial: uniphier:...
122
  	.name = "uniphier-uart",
d064cbfff   Masahiro Yamada   dm: serial: use D...
123
  	.id = UCLASS_SERIAL,
6d99cfaee   Masahiro Yamada   serial: uniphier:...
124
  	.of_match = uniphier_uart_of_match,
d064cbfff   Masahiro Yamada   dm: serial: use D...
125
  	.probe = uniphier_serial_probe,
d064cbfff   Masahiro Yamada   dm: serial: use D...
126
  	.priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data),
d064cbfff   Masahiro Yamada   dm: serial: use D...
127
  	.ops = &uniphier_serial_ops,
d064cbfff   Masahiro Yamada   dm: serial: use D...
128
  };