Blame view
drivers/serial/serial_uniphier.c
3.37 KB
7f368553f serial: add UniPh... |
1 |
/* |
4e3d84066 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 serial: add UniPh... |
5 |
* |
7f368553f serial: add UniPh... |
6 7 |
* SPDX-License-Identifier: GPL-2.0+ */ |
4af0d7e87 dm: Fix up inclus... |
8 |
#include <common.h> |
9d922450a dm: Use dm.h head... |
9 |
#include <dm.h> |
f6e7f07c1 ARM: UniPhier: re... |
10 |
#include <linux/io.h> |
325b708a6 serial: UniPhier:... |
11 |
#include <linux/serial_reg.h> |
b37a1ccea serial: uniphier:... |
12 |
#include <linux/sizes.h> |
1221ce459 treewide: replace... |
13 |
#include <linux/errno.h> |
7f368553f serial: add UniPh... |
14 |
#include <serial.h> |
625177d27 serial: UniPhier:... |
15 |
#include <fdtdec.h> |
7f368553f serial: add UniPh... |
16 |
|
7f368553f serial: add UniPh... |
17 18 19 20 |
/* * Note: Register map is slightly different from that of 16550. */ struct uniphier_serial { |
d0c47b3ef 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 serial: add UniPh... |
34 |
}; |
d064cbfff dm: serial: use D... |
35 36 |
struct uniphier_serial_private_data { struct uniphier_serial __iomem *membase; |
6d99cfaee serial: uniphier:... |
37 |
unsigned int uartclk; |
d064cbfff dm: serial: use D... |
38 39 40 41 |
}; #define uniphier_serial_port(dev) \ ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase |
7f368553f serial: add UniPh... |
42 |
|
d9bc8fd1c serial: UniPhier:... |
43 |
static int uniphier_serial_setbrg(struct udevice *dev, int baudrate) |
7f368553f serial: add UniPh... |
44 |
{ |
6d99cfaee serial: uniphier:... |
45 |
struct uniphier_serial_private_data *priv = dev_get_priv(dev); |
d064cbfff dm: serial: use D... |
46 |
struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
7f368553f serial: add UniPh... |
47 48 |
const unsigned int mode_x_div = 16; unsigned int divisor; |
7f368553f serial: add UniPh... |
49 |
|
6d99cfaee serial: uniphier:... |
50 |
divisor = DIV_ROUND_CLOSEST(priv->uartclk, mode_x_div * baudrate); |
7f368553f serial: add UniPh... |
51 |
|
d0c47b3ef serial: UniPhier:... |
52 |
writel(divisor, &port->dlr); |
7f368553f serial: add UniPh... |
53 |
|
d064cbfff dm: serial: use D... |
54 |
return 0; |
7f368553f serial: add UniPh... |
55 |
} |
d064cbfff dm: serial: use D... |
56 |
static int uniphier_serial_getc(struct udevice *dev) |
7f368553f serial: add UniPh... |
57 |
{ |
d064cbfff dm: serial: use D... |
58 |
struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
7f368553f serial: add UniPh... |
59 |
|
d0c47b3ef serial: UniPhier:... |
60 |
if (!(readl(&port->lsr) & UART_LSR_DR)) |
d064cbfff dm: serial: use D... |
61 |
return -EAGAIN; |
7f368553f serial: add UniPh... |
62 |
|
d0c47b3ef serial: UniPhier:... |
63 |
return readl(&port->rx); |
7f368553f serial: add UniPh... |
64 |
} |
d064cbfff dm: serial: use D... |
65 |
static int uniphier_serial_putc(struct udevice *dev, const char c) |
7f368553f serial: add UniPh... |
66 |
{ |
d064cbfff dm: serial: use D... |
67 |
struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
7f368553f serial: add UniPh... |
68 |
|
d0c47b3ef serial: UniPhier:... |
69 |
if (!(readl(&port->lsr) & UART_LSR_THRE)) |
d064cbfff dm: serial: use D... |
70 |
return -EAGAIN; |
7f368553f serial: add UniPh... |
71 |
|
d0c47b3ef serial: UniPhier:... |
72 |
writel(c, &port->tx); |
d064cbfff dm: serial: use D... |
73 74 |
return 0; |
7f368553f serial: add UniPh... |
75 |
} |
bb72148b2 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 serial: UniPhier:... |
81 |
return readl(&port->lsr) & UART_LSR_DR; |
bb72148b2 serial: UniPhier:... |
82 |
else |
d0c47b3ef serial: UniPhier:... |
83 |
return !(readl(&port->lsr) & UART_LSR_THRE); |
bb72148b2 serial: UniPhier:... |
84 |
} |
d9bc8fd1c serial: UniPhier:... |
85 |
static int uniphier_serial_probe(struct udevice *dev) |
d064cbfff dm: serial: use D... |
86 |
{ |
6d99cfaee serial: uniphier:... |
87 |
DECLARE_GLOBAL_DATA_PTR; |
d064cbfff dm: serial: use D... |
88 |
struct uniphier_serial_private_data *priv = dev_get_priv(dev); |
099cf77c1 serial: UniPhier:... |
89 |
struct uniphier_serial __iomem *port; |
6d99cfaee serial: uniphier:... |
90 |
fdt_addr_t base; |
6d99cfaee serial: uniphier:... |
91 |
u32 tmp; |
7f368553f serial: add UniPh... |
92 |
|
a821c4af7 dm: Rename dev_ad... |
93 |
base = devfdt_get_addr(dev); |
b37a1ccea serial: uniphier:... |
94 95 |
if (base == FDT_ADDR_T_NONE) return -EINVAL; |
6d99cfaee serial: uniphier:... |
96 |
|
4e3d84066 ARM: uniphier: us... |
97 |
port = devm_ioremap(dev, base, SZ_64); |
099cf77c1 serial: UniPhier:... |
98 |
if (!port) |
d064cbfff dm: serial: use D... |
99 |
return -ENOMEM; |
7f368553f serial: add UniPh... |
100 |
|
099cf77c1 serial: UniPhier:... |
101 |
priv->membase = port; |
e160f7d43 dm: core: Replace... |
102 |
priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), |
6d99cfaee serial: uniphier:... |
103 |
"clock-frequency", 0); |
099cf77c1 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 dm: serial: use D... |
108 109 |
return 0; } |
625177d27 serial: UniPhier:... |
110 |
static const struct udevice_id uniphier_uart_of_match[] = { |
6462cdedc ARM: UniPhier: ad... |
111 112 |
{ .compatible = "socionext,uniphier-uart" }, { /* sentinel */ } |
d064cbfff dm: serial: use D... |
113 |
}; |
d064cbfff 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 serial: UniPhier:... |
118 |
.pending = uniphier_serial_pending, |
d064cbfff dm: serial: use D... |
119 120 121 |
}; U_BOOT_DRIVER(uniphier_serial) = { |
6d99cfaee serial: uniphier:... |
122 |
.name = "uniphier-uart", |
d064cbfff dm: serial: use D... |
123 |
.id = UCLASS_SERIAL, |
6d99cfaee serial: uniphier:... |
124 |
.of_match = uniphier_uart_of_match, |
d064cbfff dm: serial: use D... |
125 |
.probe = uniphier_serial_probe, |
d064cbfff dm: serial: use D... |
126 |
.priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data), |
d064cbfff dm: serial: use D... |
127 |
.ops = &uniphier_serial_ops, |
d064cbfff dm: serial: use D... |
128 |
}; |