blob: 4356b9a64efccf46d0721a204d0a6aac77d394c6 [file] [log] [blame]
Valentin Longchamp6633fed2012-07-05 05:05:05 +00001/*
2 * (C) Copyright 2012
3 * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 */
23
24#include <common.h>
25#include <i2c.h>
26#include <asm/errno.h>
27
28/* GPIO Pin from kirkwood connected to PROGRAM_B pin of the xilinx FPGA */
29#define KM_XLX_PROGRAM_B_PIN 39
30
31#define BOCO_ADDR 0x10
32
33#define ID_REG 0x00
34#define BOCO2_ID 0x5b
35
36static int check_boco2(void)
37{
38 int ret;
39 u8 id;
40
41 ret = i2c_read(BOCO_ADDR, ID_REG, 1, &id, 1);
42 if (ret) {
43 printf("%s: error reading the BOCO id !!\n", __func__);
44 return ret;
45 }
46
47 return (id == BOCO2_ID);
48}
49
50static int boco_clear_bits(u8 reg, u8 flags)
51{
52 int ret;
53 u8 regval;
54
55 /* give access to the EEPROM from FPGA */
56 ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
57 if (ret) {
58 printf("%s: error reading the BOCO @%#x !!\n",
59 __func__, reg);
60 return ret;
61 }
62 regval &= ~flags;
63 ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
64 if (ret) {
65 printf("%s: error writing the BOCO @%#x !!\n",
66 __func__, reg);
67 return ret;
68 }
69
70 return 0;
71}
72
73static int boco_set_bits(u8 reg, u8 flags)
74{
75 int ret;
76 u8 regval;
77
78 /* give access to the EEPROM from FPGA */
79 ret = i2c_read(BOCO_ADDR, reg, 1, &regval, 1);
80 if (ret) {
81 printf("%s: error reading the BOCO @%#x !!\n",
82 __func__, reg);
83 return ret;
84 }
85 regval |= flags;
86 ret = i2c_write(BOCO_ADDR, reg, 1, &regval, 1);
87 if (ret) {
88 printf("%s: error writing the BOCO @%#x !!\n",
89 __func__, reg);
90 return ret;
91 }
92
93 return 0;
94}
95
96#define SPI_REG 0x06
97#define CFG_EEPROM 0x02
98#define FPGA_PROG 0x04
99#define FPGA_DONE 0x20
100
101int trigger_fpga_config(void)
102{
103 int ret = 0;
104
105 if (check_boco2()) {
106 /* we have a BOCO2, this has to be triggered here */
107
108 /* make sure the FPGA_can access the EEPROM */
109 ret = boco_clear_bits(SPI_REG, CFG_EEPROM);
110 if (ret)
111 return ret;
112
113 /* trigger the config start */
114 ret = boco_clear_bits(SPI_REG, FPGA_PROG);
115 if (ret)
116 return ret;
117
118 /* small delay for the pulse */
119 udelay(10);
120
121 /* up signal for pulse end */
122 ret = boco_set_bits(SPI_REG, FPGA_PROG);
123 if (ret)
124 return ret;
125
126 } else {
127 /* we do it the old way, with the gpio pin */
128 kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
129 kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0);
130 /* small delay for the pulse */
131 udelay(10);
132 kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN);
133 }
134
135 return 0;
136}
137
138int wait_for_fpga_config(void)
139{
140 int ret = 0;
141 u8 spictrl;
142 u32 timeout = 20000;
143
144 if (!check_boco2()) {
145 /* we do not have BOCO2, this is not really used */
146 return 0;
147 }
148
149 printf("PCIe FPGA config:");
150 do {
151 ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &spictrl, 1);
152 if (ret) {
153 printf("%s: error reading the BOCO spictrl !!\n",
154 __func__);
155 return ret;
156 }
157 if (timeout-- == 0) {
158 printf(" FPGA_DONE timeout\n");
159 return -EFAULT;
160 }
161 udelay(10);
162 } while (!(spictrl & FPGA_DONE));
163
164 printf(" done\n");
165
166 return 0;
167}
168
169#define PRST1 0x4
170#define BRIDGE_RST 0x4
171
172int fpga_reset(void)
173{
174 int ret = 0;
175
176 if (!check_boco2()) {
177 /* we do not have BOCO2, this is not really used */
178 return 0;
179 }
180
181 ret = boco_clear_bits(PRST1, BRIDGE_RST);
182 if (ret)
183 return ret;
184
185 /* small delay for the pulse */
186 udelay(10);
187
188 ret = boco_set_bits(PRST1, BRIDGE_RST);
189 if (ret)
190 return ret;
191
192 return 0;
193}
194
195/* the FPGA was configured, we configure the BOCO2 so that the EEPROM
196 * is available from the Bobcat SPI bus */
197int toggle_eeprom_spi_bus(void)
198{
199 int ret = 0;
200
201 if (!check_boco2()) {
202 /* we do not have BOCO2, this is not really used */
203 return 0;
204 }
205
206 ret = boco_set_bits(SPI_REG, CFG_EEPROM);
207 if (ret)
208 return ret;
209
210 return 0;
211}
212