blob: c43d24b26d4950d48e05cbcb652cd54842df3d95 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Dirk Eibach7c8f97d2013-06-26 16:04:27 +02002/*
3 * (C) Copyright 2012
4 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
Dirk Eibach7c8f97d2013-06-26 16:04:27 +02005 */
6
Mario Six78510212019-03-29 10:18:10 +01007#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
8
Dirk Eibach7c8f97d2013-06-26 16:04:27 +02009#include <common.h>
10#include <asm/io.h>
11#include <errno.h>
12
13#include <gdsys_fpga.h>
14
15enum {
16 MCINT_SLAVE_LINK_CHANGED_EV = 1 << 7,
17 MCINT_TX_ERROR_EV = 1 << 9,
18 MCINT_TX_BUFFER_FREE = 1 << 10,
19 MCINT_TX_PACKET_TRANSMITTED_EV = 1 << 11,
20 MCINT_RX_ERROR_EV = 1 << 13,
21 MCINT_RX_CONTENT_AVAILABLE = 1 << 14,
22 MCINT_RX_PACKET_RECEIVED_EV = 1 << 15,
23};
24
25int mclink_probe(void)
26{
27 unsigned int k;
28 int slaves = 0;
29
30 for (k = 0; k < CONFIG_SYS_MCLINK_MAX; ++k) {
31 int timeout = 0;
32 unsigned int ctr = 0;
33 u16 mc_status;
34
35 FPGA_GET_REG(k, mc_status, &mc_status);
36
37 if (!(mc_status & (1 << 15)))
38 break;
39
40 FPGA_SET_REG(k, mc_control, 0x8000);
41
42 FPGA_GET_REG(k, mc_status, &mc_status);
43 while (!(mc_status & (1 << 14))) {
44 udelay(100);
45 if (ctr++ > 500) {
46 timeout = 1;
47 break;
48 }
49 FPGA_GET_REG(k, mc_status, &mc_status);
50 }
51 if (timeout)
52 break;
53
54 printf("waited %d us for mclink %d to come up\n", ctr * 100, k);
55
56 slaves++;
57 }
58
59 return slaves;
60}
61
62int mclink_send(u8 slave, u16 addr, u16 data)
63{
64 unsigned int ctr = 0;
65 u16 int_status;
66 u16 rx_cmd_status;
67 u16 rx_cmd;
68
69 /* reset interrupt status */
70 FPGA_GET_REG(0, mc_int, &int_status);
71 FPGA_SET_REG(0, mc_int, int_status);
72
73 /* send */
74 FPGA_SET_REG(0, mc_tx_address, addr);
75 FPGA_SET_REG(0, mc_tx_data, data);
76 FPGA_SET_REG(0, mc_tx_cmd, (slave & 0x03) << 14);
77 FPGA_SET_REG(0, mc_control, 0x8001);
78
79 /* wait for reply */
80 FPGA_GET_REG(0, mc_int, &int_status);
81 while (!(int_status & MCINT_RX_PACKET_RECEIVED_EV)) {
82 udelay(100);
83 if (ctr++ > 3)
84 return -ETIMEDOUT;
85 FPGA_GET_REG(0, mc_int, &int_status);
86 }
87
88 FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status);
89 rx_cmd = (rx_cmd_status >> 12) & 0x03;
90 if (rx_cmd != 0)
91 printf("mclink_send: received cmd %d, expected %d\n", rx_cmd,
92 0);
93
94 return 0;
95}
96
97int mclink_receive(u8 slave, u16 addr, u16 *data)
98{
99 u16 rx_cmd_status;
100 u16 rx_cmd;
101 u16 int_status;
102 unsigned int ctr = 0;
103
104 /* send read request */
105 FPGA_SET_REG(0, mc_tx_address, addr);
106 FPGA_SET_REG(0, mc_tx_cmd,
107 ((slave & 0x03) << 14) | (1 << 12) | (1 << 0));
108 FPGA_SET_REG(0, mc_control, 0x8001);
109
110
111 /* wait for reply */
112 FPGA_GET_REG(0, mc_int, &int_status);
113 while (!(int_status & MCINT_RX_CONTENT_AVAILABLE)) {
114 udelay(100);
115 if (ctr++ > 3)
116 return -ETIMEDOUT;
117 FPGA_GET_REG(0, mc_int, &int_status);
118 }
119
120 /* check reply */
121 FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status);
122 if ((rx_cmd_status >> 14) != slave) {
123 printf("mclink_receive: reply from slave %d, expected %d\n",
124 rx_cmd_status >> 14, slave);
125 return -EINVAL;
126 }
127
128 rx_cmd = (rx_cmd_status >> 12) & 0x03;
129 if (rx_cmd != 1) {
130 printf("mclink_send: received cmd %d, expected %d\n",
131 rx_cmd, 1);
132 return -EIO;
133 }
134
135 FPGA_GET_REG(0, mc_rx_data, data);
136
137 return 0;
138}
Mario Six78510212019-03-29 10:18:10 +0100139
140#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */