]>
Commit | Line | Data |
---|---|---|
c9d4f46b SM |
1 | /* |
2 | * (C) Copyright 2004, Psyent Corporation <www.psyent.com> | |
3 | * Scott McNutt <smcnutt@psyent.com> | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
c9d4f46b SM |
6 | */ |
7 | ||
8 | #include <common.h> | |
220e8021 TC |
9 | #include <dm.h> |
10 | #include <errno.h> | |
8c085757 | 11 | #include <serial.h> |
315acd08 | 12 | #include <asm/io.h> |
c9d4f46b | 13 | |
315acd08 | 14 | DECLARE_GLOBAL_DATA_PTR; |
86450710 TC |
15 | |
16 | /* data register */ | |
886161a4 | 17 | #define ALTERA_JTAG_RVALID BIT(15) /* Read valid */ |
86450710 TC |
18 | |
19 | /* control register */ | |
886161a4 TC |
20 | #define ALTERA_JTAG_AC BIT(10) /* activity indicator */ |
21 | #define ALTERA_JTAG_RRDY BIT(12) /* read available */ | |
315acd08 | 22 | #define ALTERA_JTAG_WSPACE(d) ((d) >> 16) /* Write space avail */ |
220e8021 TC |
23 | /* Write fifo size. FIXME: this should be extracted with sopc2dts */ |
24 | #define ALTERA_JTAG_WRITE_DEPTH 64 | |
86450710 | 25 | |
315acd08 TC |
26 | struct altera_jtaguart_regs { |
27 | u32 data; /* Data register */ | |
28 | u32 control; /* Control register */ | |
29 | }; | |
30 | ||
31 | struct altera_jtaguart_platdata { | |
32 | struct altera_jtaguart_regs *regs; | |
33 | }; | |
c9d4f46b | 34 | |
220e8021 | 35 | static int altera_jtaguart_setbrg(struct udevice *dev, int baudrate) |
8c085757 | 36 | { |
220e8021 | 37 | return 0; |
8c085757 MV |
38 | } |
39 | ||
220e8021 | 40 | static int altera_jtaguart_putc(struct udevice *dev, const char ch) |
8c085757 | 41 | { |
220e8021 TC |
42 | struct altera_jtaguart_platdata *plat = dev->platdata; |
43 | struct altera_jtaguart_regs *const regs = plat->regs; | |
44 | u32 st = readl(®s->control); | |
45 | ||
46 | #ifdef CONFIG_ALTERA_JTAG_UART_BYPASS | |
47 | if (!(st & ALTERA_JTAG_AC)) /* no connection yet */ | |
48 | return -ENETUNREACH; | |
49 | #endif | |
50 | ||
51 | if (ALTERA_JTAG_WSPACE(st) == 0) | |
52 | return -EAGAIN; | |
53 | ||
54 | writel(ch, ®s->data); | |
55 | ||
8c085757 MV |
56 | return 0; |
57 | } | |
c9d4f46b | 58 | |
220e8021 | 59 | static int altera_jtaguart_pending(struct udevice *dev, bool input) |
c9d4f46b | 60 | { |
220e8021 TC |
61 | struct altera_jtaguart_platdata *plat = dev->platdata; |
62 | struct altera_jtaguart_regs *const regs = plat->regs; | |
63 | u32 st = readl(®s->control); | |
64 | ||
65 | if (input) | |
66 | return st & ALTERA_JTAG_RRDY ? 1 : 0; | |
67 | else | |
68 | return !(ALTERA_JTAG_WSPACE(st) == ALTERA_JTAG_WRITE_DEPTH); | |
c9d4f46b SM |
69 | } |
70 | ||
220e8021 | 71 | static int altera_jtaguart_getc(struct udevice *dev) |
c9d4f46b | 72 | { |
220e8021 TC |
73 | struct altera_jtaguart_platdata *plat = dev->platdata; |
74 | struct altera_jtaguart_regs *const regs = plat->regs; | |
75 | u32 val; | |
76 | ||
77 | val = readl(®s->data); | |
78 | ||
79 | if (!(val & ALTERA_JTAG_RVALID)) | |
80 | return -EAGAIN; | |
81 | ||
82 | return val & 0xff; | |
c9d4f46b SM |
83 | } |
84 | ||
220e8021 | 85 | static int altera_jtaguart_probe(struct udevice *dev) |
c9d4f46b | 86 | { |
220e8021 TC |
87 | #ifdef CONFIG_ALTERA_JTAG_UART_BYPASS |
88 | struct altera_jtaguart_platdata *plat = dev->platdata; | |
89 | struct altera_jtaguart_regs *const regs = plat->regs; | |
c9d4f46b | 90 | |
220e8021 TC |
91 | writel(ALTERA_JTAG_AC, ®s->control); /* clear AC flag */ |
92 | #endif | |
93 | return 0; | |
94 | } | |
95 | ||
96 | static int altera_jtaguart_ofdata_to_platdata(struct udevice *dev) | |
97 | { | |
98 | struct altera_jtaguart_platdata *plat = dev_get_platdata(dev); | |
99 | ||
a821c4af | 100 | plat->regs = map_physmem(devfdt_get_addr(dev), |
18c3f270 TC |
101 | sizeof(struct altera_jtaguart_regs), |
102 | MAP_NOCACHE); | |
220e8021 TC |
103 | |
104 | return 0; | |
c9d4f46b | 105 | } |
8c085757 | 106 | |
220e8021 TC |
107 | static const struct dm_serial_ops altera_jtaguart_ops = { |
108 | .putc = altera_jtaguart_putc, | |
109 | .pending = altera_jtaguart_pending, | |
110 | .getc = altera_jtaguart_getc, | |
111 | .setbrg = altera_jtaguart_setbrg, | |
112 | }; | |
113 | ||
114 | static const struct udevice_id altera_jtaguart_ids[] = { | |
315acd08 TC |
115 | { .compatible = "altr,juart-1.0" }, |
116 | {} | |
220e8021 TC |
117 | }; |
118 | ||
119 | U_BOOT_DRIVER(altera_jtaguart) = { | |
120 | .name = "altera_jtaguart", | |
121 | .id = UCLASS_SERIAL, | |
122 | .of_match = altera_jtaguart_ids, | |
123 | .ofdata_to_platdata = altera_jtaguart_ofdata_to_platdata, | |
124 | .platdata_auto_alloc_size = sizeof(struct altera_jtaguart_platdata), | |
125 | .probe = altera_jtaguart_probe, | |
126 | .ops = &altera_jtaguart_ops, | |
127 | .flags = DM_FLAG_PRE_RELOC, | |
8c085757 MV |
128 | }; |
129 | ||
220e8021 TC |
130 | #ifdef CONFIG_DEBUG_UART_ALTERA_JTAGUART |
131 | ||
132 | #include <debug_uart.h> | |
133 | ||
933529ce | 134 | static inline void _debug_uart_init(void) |
8c085757 | 135 | { |
8c085757 MV |
136 | } |
137 | ||
220e8021 | 138 | static inline void _debug_uart_putc(int ch) |
8c085757 | 139 | { |
220e8021 TC |
140 | struct altera_jtaguart_regs *regs = (void *)CONFIG_DEBUG_UART_BASE; |
141 | ||
142 | while (1) { | |
143 | u32 st = readl(®s->control); | |
144 | ||
145 | if (ALTERA_JTAG_WSPACE(st)) | |
146 | break; | |
147 | } | |
148 | ||
149 | writel(ch, ®s->data); | |
8c085757 | 150 | } |
220e8021 TC |
151 | |
152 | DEBUG_UART_FUNCS | |
153 | ||
154 | #endif |