1*ab88bd2bSMario Six // SPDX-License-Identifier: GPL-2.0+
2*ab88bd2bSMario Six /*
3*ab88bd2bSMario Six * (C) Copyright 2017
4*ab88bd2bSMario Six * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5*ab88bd2bSMario Six *
6*ab88bd2bSMario Six * based on the ioep-fpga driver, which is
7*ab88bd2bSMario Six *
8*ab88bd2bSMario Six * (C) Copyright 2014
9*ab88bd2bSMario Six * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
10*ab88bd2bSMario Six */
11*ab88bd2bSMario Six
12*ab88bd2bSMario Six #include <common.h>
13*ab88bd2bSMario Six #include <dm.h>
14*ab88bd2bSMario Six #include <regmap.h>
15*ab88bd2bSMario Six #include <asm/gpio.h>
16*ab88bd2bSMario Six
17*ab88bd2bSMario Six #include "ihs_fpga.h"
18*ab88bd2bSMario Six
19*ab88bd2bSMario Six /**
20*ab88bd2bSMario Six * struct ihs_fpga_priv - Private data structure for IHS FPGA driver
21*ab88bd2bSMario Six * @map: Register map for the FPGA's own register space
22*ab88bd2bSMario Six * @reset_gpio: GPIO to start FPGA reconfiguration
23*ab88bd2bSMario Six * @done_gpio: GPOI to read the 'ready' status of the FPGA
24*ab88bd2bSMario Six */
25*ab88bd2bSMario Six struct ihs_fpga_priv {
26*ab88bd2bSMario Six struct regmap *map;
27*ab88bd2bSMario Six struct gpio_desc reset_gpio;
28*ab88bd2bSMario Six struct gpio_desc done_gpio;
29*ab88bd2bSMario Six };
30*ab88bd2bSMario Six
31*ab88bd2bSMario Six /* Test pattern for reflection test */
32*ab88bd2bSMario Six const u16 REFLECTION_TESTPATTERN = 0xdead;
33*ab88bd2bSMario Six /* Delay (in ms) for each round in the reflection test */
34*ab88bd2bSMario Six const uint REFLECTION_TEST_DELAY = 100;
35*ab88bd2bSMario Six /* Maximum number of rounds in the reflection test */
36*ab88bd2bSMario Six const uint REFLECTION_TEST_ROUNDS = 5;
37*ab88bd2bSMario Six /* Delay (in ms) for each round waiting for the FPGA's done GPIO */
38*ab88bd2bSMario Six const uint FPGA_DONE_WAIT_DELAY = 100;
39*ab88bd2bSMario Six /* Maximum number of rounds for waiting for the FPGA's done GPIO */
40*ab88bd2bSMario Six const uint FPGA_DONE_WAIT_ROUND = 5;
41*ab88bd2bSMario Six
42*ab88bd2bSMario Six /**
43*ab88bd2bSMario Six * enum pcb_video_type - Video type of the PCB
44*ab88bd2bSMario Six * @PCB_DVI_SL: Video type is DVI single-link
45*ab88bd2bSMario Six * @PCB_DP_165MPIX: Video type is DisplayPort (165Mpix)
46*ab88bd2bSMario Six * @PCB_DP_300MPIX: Video type is DisplayPort (300Mpix)
47*ab88bd2bSMario Six * @PCB_HDMI: Video type is HDMI
48*ab88bd2bSMario Six * @PCB_DP_1_2: Video type is DisplayPort 1.2
49*ab88bd2bSMario Six * @PCB_HDMI_2_0: Video type is HDMI 2.0
50*ab88bd2bSMario Six */
51*ab88bd2bSMario Six enum pcb_video_type {
52*ab88bd2bSMario Six PCB_DVI_SL,
53*ab88bd2bSMario Six PCB_DP_165MPIX,
54*ab88bd2bSMario Six PCB_DP_300MPIX,
55*ab88bd2bSMario Six PCB_HDMI,
56*ab88bd2bSMario Six PCB_DP_1_2,
57*ab88bd2bSMario Six PCB_HDMI_2_0,
58*ab88bd2bSMario Six };
59*ab88bd2bSMario Six
60*ab88bd2bSMario Six /**
61*ab88bd2bSMario Six * enum pcb_transmission_type - Transmission type of the PCB
62*ab88bd2bSMario Six * @PCB_CAT_1G: Transmission type is 1G Ethernet
63*ab88bd2bSMario Six * @PCB_FIBER_3G: Transmission type is 3G Fiber
64*ab88bd2bSMario Six * @PCB_CAT_10G: Transmission type is 10G Ethernet
65*ab88bd2bSMario Six * @PCB_FIBER_10G: Transmission type is 10G Fiber
66*ab88bd2bSMario Six */
67*ab88bd2bSMario Six enum pcb_transmission_type {
68*ab88bd2bSMario Six PCB_CAT_1G,
69*ab88bd2bSMario Six PCB_FIBER_3G,
70*ab88bd2bSMario Six PCB_CAT_10G,
71*ab88bd2bSMario Six PCB_FIBER_10G,
72*ab88bd2bSMario Six };
73*ab88bd2bSMario Six
74*ab88bd2bSMario Six /**
75*ab88bd2bSMario Six * enum carrier_speed - Speed of the FPGA's carrier
76*ab88bd2bSMario Six * @CARRIER_SPEED_1G: The carrier speed is 1G
77*ab88bd2bSMario Six * @CARRIER_SPEED_2_5G: The carrier speed is 2.5G
78*ab88bd2bSMario Six * @CARRIER_SPEED_3G: The carrier speed is 3G
79*ab88bd2bSMario Six * @CARRIER_SPEED_10G: The carrier speed is 10G
80*ab88bd2bSMario Six */
81*ab88bd2bSMario Six enum carrier_speed {
82*ab88bd2bSMario Six CARRIER_SPEED_1G,
83*ab88bd2bSMario Six CARRIER_SPEED_3G,
84*ab88bd2bSMario Six CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
85*ab88bd2bSMario Six CARRIER_SPEED_10G,
86*ab88bd2bSMario Six };
87*ab88bd2bSMario Six
88*ab88bd2bSMario Six /**
89*ab88bd2bSMario Six * enum ram_config - FPGA's RAM configuration
90*ab88bd2bSMario Six * @RAM_DDR2_32BIT_295MBPS: DDR2 32 bit at 295Mb/s
91*ab88bd2bSMario Six * @RAM_DDR3_32BIT_590MBPS: DDR3 32 bit at 590Mb/s
92*ab88bd2bSMario Six * @RAM_DDR3_48BIT_590MBPS: DDR3 48 bit at 590Mb/s
93*ab88bd2bSMario Six * @RAM_DDR3_64BIT_1800MBPS: DDR3 64 bit at 1800Mb/s
94*ab88bd2bSMario Six * @RAM_DDR3_48BIT_1800MBPS: DDR3 48 bit at 1800Mb/s
95*ab88bd2bSMario Six */
96*ab88bd2bSMario Six enum ram_config {
97*ab88bd2bSMario Six RAM_DDR2_32BIT_295MBPS,
98*ab88bd2bSMario Six RAM_DDR3_32BIT_590MBPS,
99*ab88bd2bSMario Six RAM_DDR3_48BIT_590MBPS,
100*ab88bd2bSMario Six RAM_DDR3_64BIT_1800MBPS,
101*ab88bd2bSMario Six RAM_DDR3_48BIT_1800MBPS,
102*ab88bd2bSMario Six };
103*ab88bd2bSMario Six
104*ab88bd2bSMario Six /**
105*ab88bd2bSMario Six * enum sysclock - Speed of the FPGA's system clock
106*ab88bd2bSMario Six * @SYSCLK_147456: System clock is 147.456 MHz
107*ab88bd2bSMario Six */
108*ab88bd2bSMario Six enum sysclock {
109*ab88bd2bSMario Six SYSCLK_147456,
110*ab88bd2bSMario Six };
111*ab88bd2bSMario Six
112*ab88bd2bSMario Six /**
113*ab88bd2bSMario Six * struct fpga_versions - Data read from the versions register
114*ab88bd2bSMario Six * @video_channel: Is the FPGA for a video channel (true) or main
115*ab88bd2bSMario Six * channel (false) device?
116*ab88bd2bSMario Six * @con_side: Is the FPGA for a CON (true) or a CPU (false) device?
117*ab88bd2bSMario Six * @pcb_video_type: Defines for whch video type the FPGA is configured
118*ab88bd2bSMario Six * @pcb_transmission_type: Defines for which transmission type the FPGA is
119*ab88bd2bSMario Six * configured
120*ab88bd2bSMario Six * @hw_version: Hardware version of the FPGA
121*ab88bd2bSMario Six */
122*ab88bd2bSMario Six struct fpga_versions {
123*ab88bd2bSMario Six bool video_channel;
124*ab88bd2bSMario Six bool con_side;
125*ab88bd2bSMario Six enum pcb_video_type pcb_video_type;
126*ab88bd2bSMario Six enum pcb_transmission_type pcb_transmission_type;
127*ab88bd2bSMario Six unsigned int hw_version;
128*ab88bd2bSMario Six };
129*ab88bd2bSMario Six
130*ab88bd2bSMario Six /**
131*ab88bd2bSMario Six * struct fpga_features - Data read from the features register
132*ab88bd2bSMario Six * @video_channels: Number of video channels supported
133*ab88bd2bSMario Six * @carriers: Number of carrier channels supported
134*ab88bd2bSMario Six * @carrier_speed: Speed of carriers
135*ab88bd2bSMario Six * @ram_config: RAM configuration of FPGA
136*ab88bd2bSMario Six * @sysclock: System clock speed of FPGA
137*ab88bd2bSMario Six * @pcm_tx: Support for PCM transmission
138*ab88bd2bSMario Six * @pcm_rx: Support for PCM reception
139*ab88bd2bSMario Six * @spdif_tx: Support for SPDIF audio transmission
140*ab88bd2bSMario Six * @spdif_rx: Support for SPDIF audio reception
141*ab88bd2bSMario Six * @usb2: Support for transparent USB2.0
142*ab88bd2bSMario Six * @rs232: Support for bidirectional RS232
143*ab88bd2bSMario Six * @compression_type1: Support for compression type 1
144*ab88bd2bSMario Six * @compression_type2: Support for compression type 2
145*ab88bd2bSMario Six * @compression_type3: Support for compression type 3
146*ab88bd2bSMario Six * @interlace: Support for interlace image formats
147*ab88bd2bSMario Six * @osd: Support for a OSD
148*ab88bd2bSMario Six * @compression_pipes: Number of compression pipes supported
149*ab88bd2bSMario Six */
150*ab88bd2bSMario Six struct fpga_features {
151*ab88bd2bSMario Six u8 video_channels;
152*ab88bd2bSMario Six u8 carriers;
153*ab88bd2bSMario Six enum carrier_speed carrier_speed;
154*ab88bd2bSMario Six enum ram_config ram_config;
155*ab88bd2bSMario Six enum sysclock sysclock;
156*ab88bd2bSMario Six bool pcm_tx;
157*ab88bd2bSMario Six bool pcm_rx;
158*ab88bd2bSMario Six bool spdif_tx;
159*ab88bd2bSMario Six bool spdif_rx;
160*ab88bd2bSMario Six bool usb2;
161*ab88bd2bSMario Six bool rs232;
162*ab88bd2bSMario Six bool compression_type1;
163*ab88bd2bSMario Six bool compression_type2;
164*ab88bd2bSMario Six bool compression_type3;
165*ab88bd2bSMario Six bool interlace;
166*ab88bd2bSMario Six bool osd;
167*ab88bd2bSMario Six bool compression_pipes;
168*ab88bd2bSMario Six };
169*ab88bd2bSMario Six
170*ab88bd2bSMario Six #ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
171*ab88bd2bSMario Six
172*ab88bd2bSMario Six /**
173*ab88bd2bSMario Six * get_versions() - Fill structure with info from version register.
174*ab88bd2bSMario Six * @dev: FPGA device to be queried for information
175*ab88bd2bSMario Six * @versions: Pointer to the structure to fill with information from the
176*ab88bd2bSMario Six * versions register
177*ab88bd2bSMario Six * Return: 0
178*ab88bd2bSMario Six */
get_versions(struct udevice * dev,struct fpga_versions * versions)179*ab88bd2bSMario Six static int get_versions(struct udevice *dev, struct fpga_versions *versions)
180*ab88bd2bSMario Six {
181*ab88bd2bSMario Six struct ihs_fpga_priv *priv = dev_get_priv(dev);
182*ab88bd2bSMario Six enum {
183*ab88bd2bSMario Six VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
184*ab88bd2bSMario Six VERSIONS_FPGA_CON_SIDE = BIT(13),
185*ab88bd2bSMario Six VERSIONS_FPGA_SC = BIT(14),
186*ab88bd2bSMario Six VERSIONS_PCB_CON = BIT(9),
187*ab88bd2bSMario Six VERSIONS_PCB_SC = BIT(8),
188*ab88bd2bSMario Six VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
189*ab88bd2bSMario Six VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
190*ab88bd2bSMario Six VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
191*ab88bd2bSMario Six VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
192*ab88bd2bSMario Six VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
193*ab88bd2bSMario Six VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
194*ab88bd2bSMario Six VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
195*ab88bd2bSMario Six VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
196*ab88bd2bSMario Six VERSIONS_HW_VER_MASK = 0xf << 0,
197*ab88bd2bSMario Six };
198*ab88bd2bSMario Six u16 raw_versions;
199*ab88bd2bSMario Six
200*ab88bd2bSMario Six memset(versions, 0, sizeof(struct fpga_versions));
201*ab88bd2bSMario Six
202*ab88bd2bSMario Six ihs_fpga_get(priv->map, versions, &raw_versions);
203*ab88bd2bSMario Six
204*ab88bd2bSMario Six versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
205*ab88bd2bSMario Six versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
206*ab88bd2bSMario Six
207*ab88bd2bSMario Six switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
208*ab88bd2bSMario Six case VERSIONS_PCB_VIDEO_DP_1_2:
209*ab88bd2bSMario Six versions->pcb_video_type = PCB_DP_1_2;
210*ab88bd2bSMario Six break;
211*ab88bd2bSMario Six
212*ab88bd2bSMario Six case VERSIONS_PCB_VIDEO_HDMI_2_0:
213*ab88bd2bSMario Six versions->pcb_video_type = PCB_HDMI_2_0;
214*ab88bd2bSMario Six break;
215*ab88bd2bSMario Six }
216*ab88bd2bSMario Six
217*ab88bd2bSMario Six switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
218*ab88bd2bSMario Six case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
219*ab88bd2bSMario Six versions->pcb_transmission_type = PCB_FIBER_10G;
220*ab88bd2bSMario Six break;
221*ab88bd2bSMario Six
222*ab88bd2bSMario Six case VERSIONS_PCB_TRANSMISSION_CAT_10G:
223*ab88bd2bSMario Six versions->pcb_transmission_type = PCB_CAT_10G;
224*ab88bd2bSMario Six break;
225*ab88bd2bSMario Six
226*ab88bd2bSMario Six case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
227*ab88bd2bSMario Six versions->pcb_transmission_type = PCB_FIBER_3G;
228*ab88bd2bSMario Six break;
229*ab88bd2bSMario Six
230*ab88bd2bSMario Six case VERSIONS_PCB_TRANSMISSION_CAT_1G:
231*ab88bd2bSMario Six versions->pcb_transmission_type = PCB_CAT_1G;
232*ab88bd2bSMario Six break;
233*ab88bd2bSMario Six }
234*ab88bd2bSMario Six
235*ab88bd2bSMario Six versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
236*ab88bd2bSMario Six
237*ab88bd2bSMario Six return 0;
238*ab88bd2bSMario Six }
239*ab88bd2bSMario Six
240*ab88bd2bSMario Six /**
241*ab88bd2bSMario Six * get_features() - Fill structure with info from features register.
242*ab88bd2bSMario Six * @dev: FPGA device to be queried for information
243*ab88bd2bSMario Six * @features: Pointer to the structure to fill with information from the
244*ab88bd2bSMario Six * features register
245*ab88bd2bSMario Six * Return: 0
246*ab88bd2bSMario Six */
get_features(struct udevice * dev,struct fpga_features * features)247*ab88bd2bSMario Six static int get_features(struct udevice *dev, struct fpga_features *features)
248*ab88bd2bSMario Six {
249*ab88bd2bSMario Six struct ihs_fpga_priv *priv = dev_get_priv(dev);
250*ab88bd2bSMario Six enum {
251*ab88bd2bSMario Six FEATURE_SPDIF_RX = BIT(15),
252*ab88bd2bSMario Six FEATURE_SPDIF_TX = BIT(14),
253*ab88bd2bSMario Six FEATURE_PCM_RX = BIT(13),
254*ab88bd2bSMario Six FEATURE_PCM_TX = BIT(12),
255*ab88bd2bSMario Six FEATURE_RAM_MASK = GENMASK(11, 8),
256*ab88bd2bSMario Six FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
257*ab88bd2bSMario Six FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
258*ab88bd2bSMario Six FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
259*ab88bd2bSMario Six FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
260*ab88bd2bSMario Six FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
261*ab88bd2bSMario Six FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
262*ab88bd2bSMario Six FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
263*ab88bd2bSMario Six FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
264*ab88bd2bSMario Six FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
265*ab88bd2bSMario Six FEATURE_CARRIERS_MASK = GENMASK(5, 4),
266*ab88bd2bSMario Six FEATURE_CARRIERS_0 = 0x0 << 4,
267*ab88bd2bSMario Six FEATURE_CARRIERS_1 = 0x1 << 4,
268*ab88bd2bSMario Six FEATURE_CARRIERS_2 = 0x2 << 4,
269*ab88bd2bSMario Six FEATURE_CARRIERS_4 = 0x3 << 4,
270*ab88bd2bSMario Six FEATURE_USB2 = BIT(3),
271*ab88bd2bSMario Six FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
272*ab88bd2bSMario Six FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
273*ab88bd2bSMario Six FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
274*ab88bd2bSMario Six FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
275*ab88bd2bSMario Six FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
276*ab88bd2bSMario Six };
277*ab88bd2bSMario Six
278*ab88bd2bSMario Six enum {
279*ab88bd2bSMario Six EXT_FEATURE_OSD = BIT(15),
280*ab88bd2bSMario Six EXT_FEATURE_ETHERNET = BIT(9),
281*ab88bd2bSMario Six EXT_FEATURE_INTERLACE = BIT(8),
282*ab88bd2bSMario Six EXT_FEATURE_RS232 = BIT(7),
283*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
284*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
285*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
286*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
287*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
288*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
289*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
290*ab88bd2bSMario Six };
291*ab88bd2bSMario Six
292*ab88bd2bSMario Six u16 raw_features;
293*ab88bd2bSMario Six u16 raw_extended_features;
294*ab88bd2bSMario Six
295*ab88bd2bSMario Six memset(features, 0, sizeof(struct fpga_features));
296*ab88bd2bSMario Six
297*ab88bd2bSMario Six ihs_fpga_get(priv->map, features, &raw_features);
298*ab88bd2bSMario Six ihs_fpga_get(priv->map, extended_features, &raw_extended_features);
299*ab88bd2bSMario Six
300*ab88bd2bSMario Six switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
301*ab88bd2bSMario Six case FEATURE_VIDEOCHANNELS_0:
302*ab88bd2bSMario Six features->video_channels = 0;
303*ab88bd2bSMario Six break;
304*ab88bd2bSMario Six
305*ab88bd2bSMario Six case FEATURE_VIDEOCHANNELS_1:
306*ab88bd2bSMario Six features->video_channels = 1;
307*ab88bd2bSMario Six break;
308*ab88bd2bSMario Six
309*ab88bd2bSMario Six case FEATURE_VIDEOCHANNELS_1_1:
310*ab88bd2bSMario Six case FEATURE_VIDEOCHANNELS_2:
311*ab88bd2bSMario Six features->video_channels = 2;
312*ab88bd2bSMario Six break;
313*ab88bd2bSMario Six };
314*ab88bd2bSMario Six
315*ab88bd2bSMario Six switch (raw_features & FEATURE_CARRIERS_MASK) {
316*ab88bd2bSMario Six case FEATURE_CARRIERS_0:
317*ab88bd2bSMario Six features->carriers = 0;
318*ab88bd2bSMario Six break;
319*ab88bd2bSMario Six
320*ab88bd2bSMario Six case FEATURE_CARRIERS_1:
321*ab88bd2bSMario Six features->carriers = 1;
322*ab88bd2bSMario Six break;
323*ab88bd2bSMario Six
324*ab88bd2bSMario Six case FEATURE_CARRIERS_2:
325*ab88bd2bSMario Six features->carriers = 2;
326*ab88bd2bSMario Six break;
327*ab88bd2bSMario Six
328*ab88bd2bSMario Six case FEATURE_CARRIERS_4:
329*ab88bd2bSMario Six features->carriers = 4;
330*ab88bd2bSMario Six break;
331*ab88bd2bSMario Six }
332*ab88bd2bSMario Six
333*ab88bd2bSMario Six switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
334*ab88bd2bSMario Six case FEATURE_CARRIER_SPEED_1G:
335*ab88bd2bSMario Six features->carrier_speed = CARRIER_SPEED_1G;
336*ab88bd2bSMario Six break;
337*ab88bd2bSMario Six case FEATURE_CARRIER_SPEED_2_5G:
338*ab88bd2bSMario Six features->carrier_speed = CARRIER_SPEED_2_5G;
339*ab88bd2bSMario Six break;
340*ab88bd2bSMario Six case FEATURE_CARRIER_SPEED_10G:
341*ab88bd2bSMario Six features->carrier_speed = CARRIER_SPEED_10G;
342*ab88bd2bSMario Six break;
343*ab88bd2bSMario Six }
344*ab88bd2bSMario Six
345*ab88bd2bSMario Six switch (raw_features & FEATURE_RAM_MASK) {
346*ab88bd2bSMario Six case FEATURE_RAM_DDR2_32BIT_295MBPS:
347*ab88bd2bSMario Six features->ram_config = RAM_DDR2_32BIT_295MBPS;
348*ab88bd2bSMario Six break;
349*ab88bd2bSMario Six
350*ab88bd2bSMario Six case FEATURE_RAM_DDR3_32BIT_590MBPS:
351*ab88bd2bSMario Six features->ram_config = RAM_DDR3_32BIT_590MBPS;
352*ab88bd2bSMario Six break;
353*ab88bd2bSMario Six
354*ab88bd2bSMario Six case FEATURE_RAM_DDR3_48BIT_590MBPS:
355*ab88bd2bSMario Six features->ram_config = RAM_DDR3_48BIT_590MBPS;
356*ab88bd2bSMario Six break;
357*ab88bd2bSMario Six
358*ab88bd2bSMario Six case FEATURE_RAM_DDR3_64BIT_1800MBPS:
359*ab88bd2bSMario Six features->ram_config = RAM_DDR3_64BIT_1800MBPS;
360*ab88bd2bSMario Six break;
361*ab88bd2bSMario Six
362*ab88bd2bSMario Six case FEATURE_RAM_DDR3_48BIT_1800MBPS:
363*ab88bd2bSMario Six features->ram_config = RAM_DDR3_48BIT_1800MBPS;
364*ab88bd2bSMario Six break;
365*ab88bd2bSMario Six }
366*ab88bd2bSMario Six
367*ab88bd2bSMario Six features->pcm_tx = raw_features & FEATURE_PCM_TX;
368*ab88bd2bSMario Six features->pcm_rx = raw_features & FEATURE_PCM_RX;
369*ab88bd2bSMario Six features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
370*ab88bd2bSMario Six features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
371*ab88bd2bSMario Six features->usb2 = raw_features & FEATURE_USB2;
372*ab88bd2bSMario Six features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
373*ab88bd2bSMario Six features->compression_type1 = raw_extended_features &
374*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_TYPE1;
375*ab88bd2bSMario Six features->compression_type2 = raw_extended_features &
376*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_TYPE2;
377*ab88bd2bSMario Six features->compression_type3 = raw_extended_features &
378*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_TYPE3;
379*ab88bd2bSMario Six features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
380*ab88bd2bSMario Six features->osd = raw_extended_features & EXT_FEATURE_OSD;
381*ab88bd2bSMario Six features->compression_pipes = raw_extended_features &
382*ab88bd2bSMario Six EXT_FEATURE_COMPRESSION_PERF_MASK;
383*ab88bd2bSMario Six
384*ab88bd2bSMario Six return 0;
385*ab88bd2bSMario Six }
386*ab88bd2bSMario Six
387*ab88bd2bSMario Six #else
388*ab88bd2bSMario Six
389*ab88bd2bSMario Six /**
390*ab88bd2bSMario Six * get_versions() - Fill structure with info from version register.
391*ab88bd2bSMario Six * @fpga: Identifier of the FPGA device to be queried for information
392*ab88bd2bSMario Six * @versions: Pointer to the structure to fill with information from the
393*ab88bd2bSMario Six * versions register
394*ab88bd2bSMario Six *
395*ab88bd2bSMario Six * This is the legacy version and should be considered deprecated for new
396*ab88bd2bSMario Six * devices.
397*ab88bd2bSMario Six *
398*ab88bd2bSMario Six * Return: 0
399*ab88bd2bSMario Six */
get_versions(unsigned int fpga,struct fpga_versions * versions)400*ab88bd2bSMario Six static int get_versions(unsigned int fpga, struct fpga_versions *versions)
401*ab88bd2bSMario Six {
402*ab88bd2bSMario Six enum {
403*ab88bd2bSMario Six /* HW version encoding is a mess, leave it for the moment */
404*ab88bd2bSMario Six VERSIONS_HW_VER_MASK = 0xf << 0,
405*ab88bd2bSMario Six VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
406*ab88bd2bSMario Six VERSIONS_SFP = BIT(5),
407*ab88bd2bSMario Six VERSIONS_VIDEO_MASK = 0x7 << 6,
408*ab88bd2bSMario Six VERSIONS_VIDEO_DVI = 0x0 << 6,
409*ab88bd2bSMario Six VERSIONS_VIDEO_DP_165 = 0x1 << 6,
410*ab88bd2bSMario Six VERSIONS_VIDEO_DP_300 = 0x2 << 6,
411*ab88bd2bSMario Six VERSIONS_VIDEO_HDMI = 0x3 << 6,
412*ab88bd2bSMario Six VERSIONS_UT_MASK = 0xf << 12,
413*ab88bd2bSMario Six VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
414*ab88bd2bSMario Six VERSIONS_UT_MAIN_USER = 0x1 << 12,
415*ab88bd2bSMario Six VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
416*ab88bd2bSMario Six VERSIONS_UT_VIDEO_USER = 0x3 << 12,
417*ab88bd2bSMario Six };
418*ab88bd2bSMario Six u16 raw_versions;
419*ab88bd2bSMario Six
420*ab88bd2bSMario Six memset(versions, 0, sizeof(struct fpga_versions));
421*ab88bd2bSMario Six
422*ab88bd2bSMario Six FPGA_GET_REG(fpga, versions, &raw_versions);
423*ab88bd2bSMario Six
424*ab88bd2bSMario Six switch (raw_versions & VERSIONS_UT_MASK) {
425*ab88bd2bSMario Six case VERSIONS_UT_MAIN_SERVER:
426*ab88bd2bSMario Six versions->video_channel = false;
427*ab88bd2bSMario Six versions->con_side = false;
428*ab88bd2bSMario Six break;
429*ab88bd2bSMario Six
430*ab88bd2bSMario Six case VERSIONS_UT_MAIN_USER:
431*ab88bd2bSMario Six versions->video_channel = false;
432*ab88bd2bSMario Six versions->con_side = true;
433*ab88bd2bSMario Six break;
434*ab88bd2bSMario Six
435*ab88bd2bSMario Six case VERSIONS_UT_VIDEO_SERVER:
436*ab88bd2bSMario Six versions->video_channel = true;
437*ab88bd2bSMario Six versions->con_side = false;
438*ab88bd2bSMario Six break;
439*ab88bd2bSMario Six
440*ab88bd2bSMario Six case VERSIONS_UT_VIDEO_USER:
441*ab88bd2bSMario Six versions->video_channel = true;
442*ab88bd2bSMario Six versions->con_side = true;
443*ab88bd2bSMario Six break;
444*ab88bd2bSMario Six }
445*ab88bd2bSMario Six
446*ab88bd2bSMario Six switch (raw_versions & VERSIONS_VIDEO_MASK) {
447*ab88bd2bSMario Six case VERSIONS_VIDEO_DVI:
448*ab88bd2bSMario Six versions->pcb_video_type = PCB_DVI_SL;
449*ab88bd2bSMario Six break;
450*ab88bd2bSMario Six
451*ab88bd2bSMario Six case VERSIONS_VIDEO_DP_165:
452*ab88bd2bSMario Six versions->pcb_video_type = PCB_DP_165MPIX;
453*ab88bd2bSMario Six break;
454*ab88bd2bSMario Six
455*ab88bd2bSMario Six case VERSIONS_VIDEO_DP_300:
456*ab88bd2bSMario Six versions->pcb_video_type = PCB_DP_300MPIX;
457*ab88bd2bSMario Six break;
458*ab88bd2bSMario Six
459*ab88bd2bSMario Six case VERSIONS_VIDEO_HDMI:
460*ab88bd2bSMario Six versions->pcb_video_type = PCB_HDMI;
461*ab88bd2bSMario Six break;
462*ab88bd2bSMario Six }
463*ab88bd2bSMario Six
464*ab88bd2bSMario Six versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
465*ab88bd2bSMario Six
466*ab88bd2bSMario Six if (raw_versions & VERSIONS_SFP)
467*ab88bd2bSMario Six versions->pcb_transmission_type = PCB_FIBER_3G;
468*ab88bd2bSMario Six else
469*ab88bd2bSMario Six versions->pcb_transmission_type = PCB_CAT_1G;
470*ab88bd2bSMario Six
471*ab88bd2bSMario Six return 0;
472*ab88bd2bSMario Six }
473*ab88bd2bSMario Six
474*ab88bd2bSMario Six /**
475*ab88bd2bSMario Six * get_features() - Fill structure with info from features register.
476*ab88bd2bSMario Six * @fpga: Identifier of the FPGA device to be queried for information
477*ab88bd2bSMario Six * @features: Pointer to the structure to fill with information from the
478*ab88bd2bSMario Six * features register
479*ab88bd2bSMario Six *
480*ab88bd2bSMario Six * This is the legacy version and should be considered deprecated for new
481*ab88bd2bSMario Six * devices.
482*ab88bd2bSMario Six *
483*ab88bd2bSMario Six * Return: 0
484*ab88bd2bSMario Six */
get_features(unsigned int fpga,struct fpga_features * features)485*ab88bd2bSMario Six static int get_features(unsigned int fpga, struct fpga_features *features)
486*ab88bd2bSMario Six {
487*ab88bd2bSMario Six enum {
488*ab88bd2bSMario Six FEATURE_CARRIER_SPEED_2_5 = BIT(4),
489*ab88bd2bSMario Six FEATURE_RAM_MASK = 0x7 << 5,
490*ab88bd2bSMario Six FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
491*ab88bd2bSMario Six FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
492*ab88bd2bSMario Six FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
493*ab88bd2bSMario Six FEATURE_PCM_AUDIO_TX = BIT(9),
494*ab88bd2bSMario Six FEATURE_PCM_AUDIO_RX = BIT(10),
495*ab88bd2bSMario Six FEATURE_OSD = BIT(11),
496*ab88bd2bSMario Six FEATURE_USB20 = BIT(12),
497*ab88bd2bSMario Six FEATURE_COMPRESSION_MASK = 7 << 13,
498*ab88bd2bSMario Six FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
499*ab88bd2bSMario Six FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
500*ab88bd2bSMario Six FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
501*ab88bd2bSMario Six };
502*ab88bd2bSMario Six
503*ab88bd2bSMario Six enum {
504*ab88bd2bSMario Six EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
505*ab88bd2bSMario Six EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
506*ab88bd2bSMario Six EXTENDED_FEATURE_RS232 = BIT(2),
507*ab88bd2bSMario Six EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
508*ab88bd2bSMario Six EXTENDED_FEATURE_INTERLACE = BIT(4),
509*ab88bd2bSMario Six };
510*ab88bd2bSMario Six
511*ab88bd2bSMario Six u16 raw_features;
512*ab88bd2bSMario Six u16 raw_extended_features;
513*ab88bd2bSMario Six
514*ab88bd2bSMario Six memset(features, 0, sizeof(struct fpga_features));
515*ab88bd2bSMario Six
516*ab88bd2bSMario Six FPGA_GET_REG(fpga, fpga_features, &raw_features);
517*ab88bd2bSMario Six FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
518*ab88bd2bSMario Six
519*ab88bd2bSMario Six features->video_channels = raw_features & 0x3;
520*ab88bd2bSMario Six features->carriers = (raw_features >> 2) & 0x3;
521*ab88bd2bSMario Six
522*ab88bd2bSMario Six features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
523*ab88bd2bSMario Six ? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
524*ab88bd2bSMario Six
525*ab88bd2bSMario Six switch (raw_features & FEATURE_RAM_MASK) {
526*ab88bd2bSMario Six case FEATURE_RAM_DDR2_32BIT:
527*ab88bd2bSMario Six features->ram_config = RAM_DDR2_32BIT_295MBPS;
528*ab88bd2bSMario Six break;
529*ab88bd2bSMario Six
530*ab88bd2bSMario Six case FEATURE_RAM_DDR3_32BIT:
531*ab88bd2bSMario Six features->ram_config = RAM_DDR3_32BIT_590MBPS;
532*ab88bd2bSMario Six break;
533*ab88bd2bSMario Six
534*ab88bd2bSMario Six case FEATURE_RAM_DDR3_48BIT:
535*ab88bd2bSMario Six features->ram_config = RAM_DDR3_48BIT_590MBPS;
536*ab88bd2bSMario Six break;
537*ab88bd2bSMario Six }
538*ab88bd2bSMario Six
539*ab88bd2bSMario Six features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
540*ab88bd2bSMario Six features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
541*ab88bd2bSMario Six features->spdif_tx = raw_extended_features &
542*ab88bd2bSMario Six EXTENDED_FEATURE_SPDIF_AUDIO_TX;
543*ab88bd2bSMario Six features->spdif_rx = raw_extended_features &
544*ab88bd2bSMario Six EXTENDED_FEATURE_SPDIF_AUDIO_RX;
545*ab88bd2bSMario Six
546*ab88bd2bSMario Six features->usb2 = raw_features & FEATURE_USB20;
547*ab88bd2bSMario Six features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
548*ab88bd2bSMario Six
549*ab88bd2bSMario Six features->compression_type1 = false;
550*ab88bd2bSMario Six features->compression_type2 = false;
551*ab88bd2bSMario Six features->compression_type3 = false;
552*ab88bd2bSMario Six switch (raw_features & FEATURE_COMPRESSION_MASK) {
553*ab88bd2bSMario Six case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
554*ab88bd2bSMario Six features->compression_type3 = true;
555*ab88bd2bSMario Six /* fall-through */
556*ab88bd2bSMario Six case FEATURE_COMPRESSION_TYPE1_TYPE2:
557*ab88bd2bSMario Six features->compression_type2 = true;
558*ab88bd2bSMario Six /* fall-through */
559*ab88bd2bSMario Six case FEATURE_COMPRESSION_TYPE1:
560*ab88bd2bSMario Six features->compression_type1 = true;
561*ab88bd2bSMario Six break;
562*ab88bd2bSMario Six }
563*ab88bd2bSMario Six
564*ab88bd2bSMario Six features->interlace = raw_extended_features &
565*ab88bd2bSMario Six EXTENDED_FEATURE_INTERLACE;
566*ab88bd2bSMario Six features->osd = raw_features & FEATURE_OSD;
567*ab88bd2bSMario Six features->compression_pipes = raw_extended_features &
568*ab88bd2bSMario Six EXTENDED_FEATURE_COMPRESSION_PIPES;
569*ab88bd2bSMario Six
570*ab88bd2bSMario Six return 0;
571*ab88bd2bSMario Six }
572*ab88bd2bSMario Six
573*ab88bd2bSMario Six #endif
574*ab88bd2bSMario Six
575*ab88bd2bSMario Six /**
576*ab88bd2bSMario Six * fpga_print_info() - Print information about FPGA device
577*ab88bd2bSMario Six * @dev: FPGA device to print information about
578*ab88bd2bSMario Six */
fpga_print_info(struct udevice * dev)579*ab88bd2bSMario Six static void fpga_print_info(struct udevice *dev)
580*ab88bd2bSMario Six {
581*ab88bd2bSMario Six struct ihs_fpga_priv *priv = dev_get_priv(dev);
582*ab88bd2bSMario Six u16 fpga_version;
583*ab88bd2bSMario Six struct fpga_versions versions;
584*ab88bd2bSMario Six struct fpga_features features;
585*ab88bd2bSMario Six
586*ab88bd2bSMario Six ihs_fpga_get(priv->map, fpga_version, &fpga_version);
587*ab88bd2bSMario Six get_versions(dev, &versions);
588*ab88bd2bSMario Six get_features(dev, &features);
589*ab88bd2bSMario Six
590*ab88bd2bSMario Six if (versions.video_channel)
591*ab88bd2bSMario Six printf("Videochannel");
592*ab88bd2bSMario Six else
593*ab88bd2bSMario Six printf("Mainchannel");
594*ab88bd2bSMario Six
595*ab88bd2bSMario Six if (versions.con_side)
596*ab88bd2bSMario Six printf(" User");
597*ab88bd2bSMario Six else
598*ab88bd2bSMario Six printf(" Server");
599*ab88bd2bSMario Six
600*ab88bd2bSMario Six switch (versions.pcb_transmission_type) {
601*ab88bd2bSMario Six case PCB_CAT_1G:
602*ab88bd2bSMario Six case PCB_CAT_10G:
603*ab88bd2bSMario Six printf(" CAT");
604*ab88bd2bSMario Six break;
605*ab88bd2bSMario Six case PCB_FIBER_3G:
606*ab88bd2bSMario Six case PCB_FIBER_10G:
607*ab88bd2bSMario Six printf(" Fiber");
608*ab88bd2bSMario Six break;
609*ab88bd2bSMario Six };
610*ab88bd2bSMario Six
611*ab88bd2bSMario Six switch (versions.pcb_video_type) {
612*ab88bd2bSMario Six case PCB_DVI_SL:
613*ab88bd2bSMario Six printf(" DVI,");
614*ab88bd2bSMario Six break;
615*ab88bd2bSMario Six case PCB_DP_165MPIX:
616*ab88bd2bSMario Six printf(" DP 165MPix/s,");
617*ab88bd2bSMario Six break;
618*ab88bd2bSMario Six case PCB_DP_300MPIX:
619*ab88bd2bSMario Six printf(" DP 300MPix/s,");
620*ab88bd2bSMario Six break;
621*ab88bd2bSMario Six case PCB_HDMI:
622*ab88bd2bSMario Six printf(" HDMI,");
623*ab88bd2bSMario Six break;
624*ab88bd2bSMario Six case PCB_DP_1_2:
625*ab88bd2bSMario Six printf(" DP 1.2,");
626*ab88bd2bSMario Six break;
627*ab88bd2bSMario Six case PCB_HDMI_2_0:
628*ab88bd2bSMario Six printf(" HDMI 2.0,");
629*ab88bd2bSMario Six break;
630*ab88bd2bSMario Six }
631*ab88bd2bSMario Six
632*ab88bd2bSMario Six printf(" FPGA V %d.%02d\n features: ",
633*ab88bd2bSMario Six fpga_version / 100, fpga_version % 100);
634*ab88bd2bSMario Six
635*ab88bd2bSMario Six if (!features.compression_type1 &&
636*ab88bd2bSMario Six !features.compression_type2 &&
637*ab88bd2bSMario Six !features.compression_type3)
638*ab88bd2bSMario Six printf("no compression, ");
639*ab88bd2bSMario Six
640*ab88bd2bSMario Six if (features.compression_type1)
641*ab88bd2bSMario Six printf("type1, ");
642*ab88bd2bSMario Six
643*ab88bd2bSMario Six if (features.compression_type2)
644*ab88bd2bSMario Six printf("type2, ");
645*ab88bd2bSMario Six
646*ab88bd2bSMario Six if (features.compression_type3)
647*ab88bd2bSMario Six printf("type3, ");
648*ab88bd2bSMario Six
649*ab88bd2bSMario Six printf("%sosd", features.osd ? "" : "no ");
650*ab88bd2bSMario Six
651*ab88bd2bSMario Six if (features.pcm_rx && features.pcm_tx)
652*ab88bd2bSMario Six printf(", pcm rx+tx");
653*ab88bd2bSMario Six else if (features.pcm_rx)
654*ab88bd2bSMario Six printf(", pcm rx");
655*ab88bd2bSMario Six else if (features.pcm_tx)
656*ab88bd2bSMario Six printf(", pcm tx");
657*ab88bd2bSMario Six
658*ab88bd2bSMario Six if (features.spdif_rx && features.spdif_tx)
659*ab88bd2bSMario Six printf(", spdif rx+tx");
660*ab88bd2bSMario Six else if (features.spdif_rx)
661*ab88bd2bSMario Six printf(", spdif rx");
662*ab88bd2bSMario Six else if (features.spdif_tx)
663*ab88bd2bSMario Six printf(", spdif tx");
664*ab88bd2bSMario Six
665*ab88bd2bSMario Six puts(",\n ");
666*ab88bd2bSMario Six
667*ab88bd2bSMario Six switch (features.sysclock) {
668*ab88bd2bSMario Six case SYSCLK_147456:
669*ab88bd2bSMario Six printf("clock 147.456 MHz");
670*ab88bd2bSMario Six break;
671*ab88bd2bSMario Six }
672*ab88bd2bSMario Six
673*ab88bd2bSMario Six switch (features.ram_config) {
674*ab88bd2bSMario Six case RAM_DDR2_32BIT_295MBPS:
675*ab88bd2bSMario Six printf(", RAM 32 bit DDR2");
676*ab88bd2bSMario Six break;
677*ab88bd2bSMario Six case RAM_DDR3_32BIT_590MBPS:
678*ab88bd2bSMario Six printf(", RAM 32 bit DDR3");
679*ab88bd2bSMario Six break;
680*ab88bd2bSMario Six case RAM_DDR3_48BIT_590MBPS:
681*ab88bd2bSMario Six case RAM_DDR3_48BIT_1800MBPS:
682*ab88bd2bSMario Six printf(", RAM 48 bit DDR3");
683*ab88bd2bSMario Six break;
684*ab88bd2bSMario Six case RAM_DDR3_64BIT_1800MBPS:
685*ab88bd2bSMario Six printf(", RAM 64 bit DDR3");
686*ab88bd2bSMario Six break;
687*ab88bd2bSMario Six }
688*ab88bd2bSMario Six
689*ab88bd2bSMario Six printf(", %d carrier(s)", features.carriers);
690*ab88bd2bSMario Six
691*ab88bd2bSMario Six switch (features.carrier_speed) {
692*ab88bd2bSMario Six case CARRIER_SPEED_1G:
693*ab88bd2bSMario Six printf(", 1Gbit/s");
694*ab88bd2bSMario Six break;
695*ab88bd2bSMario Six case CARRIER_SPEED_3G:
696*ab88bd2bSMario Six printf(", 3Gbit/s");
697*ab88bd2bSMario Six break;
698*ab88bd2bSMario Six case CARRIER_SPEED_10G:
699*ab88bd2bSMario Six printf(", 10Gbit/s");
700*ab88bd2bSMario Six break;
701*ab88bd2bSMario Six }
702*ab88bd2bSMario Six
703*ab88bd2bSMario Six printf(", %d video channel(s)\n", features.video_channels);
704*ab88bd2bSMario Six }
705*ab88bd2bSMario Six
706*ab88bd2bSMario Six /**
707*ab88bd2bSMario Six * do_reflection_test() - Run reflection test on a FPGA device
708*ab88bd2bSMario Six * @dev: FPGA device to run reflection test on
709*ab88bd2bSMario Six *
710*ab88bd2bSMario Six * Return: 0 if reflection test succeeded, -ve on error
711*ab88bd2bSMario Six */
do_reflection_test(struct udevice * dev)712*ab88bd2bSMario Six static int do_reflection_test(struct udevice *dev)
713*ab88bd2bSMario Six {
714*ab88bd2bSMario Six struct ihs_fpga_priv *priv = dev_get_priv(dev);
715*ab88bd2bSMario Six int ctr = 0;
716*ab88bd2bSMario Six
717*ab88bd2bSMario Six while (1) {
718*ab88bd2bSMario Six u16 val;
719*ab88bd2bSMario Six
720*ab88bd2bSMario Six ihs_fpga_set(priv->map, reflection_low, REFLECTION_TESTPATTERN);
721*ab88bd2bSMario Six
722*ab88bd2bSMario Six ihs_fpga_get(priv->map, reflection_low, &val);
723*ab88bd2bSMario Six if (val == (~REFLECTION_TESTPATTERN & 0xffff))
724*ab88bd2bSMario Six return -EIO;
725*ab88bd2bSMario Six
726*ab88bd2bSMario Six mdelay(REFLECTION_TEST_DELAY);
727*ab88bd2bSMario Six if (ctr++ > REFLECTION_TEST_ROUNDS)
728*ab88bd2bSMario Six return 0;
729*ab88bd2bSMario Six }
730*ab88bd2bSMario Six }
731*ab88bd2bSMario Six
732*ab88bd2bSMario Six /**
733*ab88bd2bSMario Six * wait_for_fpga_done() - Wait until 'done'-flag is set for FPGA device
734*ab88bd2bSMario Six * @dev: FPGA device whose done flag to wait for
735*ab88bd2bSMario Six *
736*ab88bd2bSMario Six * This function waits until it detects that the done-GPIO's value was changed
737*ab88bd2bSMario Six * to 1 by the FPGA, which indicates that the device is configured and ready to
738*ab88bd2bSMario Six * use.
739*ab88bd2bSMario Six *
740*ab88bd2bSMario Six * Return: 0 if done flag was detected, -ve on error
741*ab88bd2bSMario Six */
wait_for_fpga_done(struct udevice * dev)742*ab88bd2bSMario Six static int wait_for_fpga_done(struct udevice *dev)
743*ab88bd2bSMario Six {
744*ab88bd2bSMario Six struct ihs_fpga_priv *priv = dev_get_priv(dev);
745*ab88bd2bSMario Six int ctr = 0;
746*ab88bd2bSMario Six int done_val;
747*ab88bd2bSMario Six
748*ab88bd2bSMario Six while (1) {
749*ab88bd2bSMario Six done_val = dm_gpio_get_value(&priv->done_gpio);
750*ab88bd2bSMario Six if (done_val < 0) {
751*ab88bd2bSMario Six debug("%s: Error while reading done-GPIO (err = %d)\n",
752*ab88bd2bSMario Six dev->name, done_val);
753*ab88bd2bSMario Six return done_val;
754*ab88bd2bSMario Six }
755*ab88bd2bSMario Six
756*ab88bd2bSMario Six if (done_val)
757*ab88bd2bSMario Six return 0;
758*ab88bd2bSMario Six
759*ab88bd2bSMario Six mdelay(FPGA_DONE_WAIT_DELAY);
760*ab88bd2bSMario Six if (ctr++ > FPGA_DONE_WAIT_ROUND) {
761*ab88bd2bSMario Six debug("%s: FPGA init failed (done not detected)\n",
762*ab88bd2bSMario Six dev->name);
763*ab88bd2bSMario Six return -EIO;
764*ab88bd2bSMario Six }
765*ab88bd2bSMario Six }
766*ab88bd2bSMario Six }
767*ab88bd2bSMario Six
ihs_fpga_probe(struct udevice * dev)768*ab88bd2bSMario Six static int ihs_fpga_probe(struct udevice *dev)
769*ab88bd2bSMario Six {
770*ab88bd2bSMario Six struct ihs_fpga_priv *priv = dev_get_priv(dev);
771*ab88bd2bSMario Six int ret;
772*ab88bd2bSMario Six
773*ab88bd2bSMario Six /* TODO(mario.six@gdsys.cc): Case of FPGA attached to MCLink bus */
774*ab88bd2bSMario Six
775*ab88bd2bSMario Six ret = regmap_init_mem(dev_ofnode(dev), &priv->map);
776*ab88bd2bSMario Six if (ret) {
777*ab88bd2bSMario Six debug("%s: Could not initialize regmap (err = %d)",
778*ab88bd2bSMario Six dev->name, ret);
779*ab88bd2bSMario Six return ret;
780*ab88bd2bSMario Six }
781*ab88bd2bSMario Six
782*ab88bd2bSMario Six ret = gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
783*ab88bd2bSMario Six GPIOD_IS_OUT);
784*ab88bd2bSMario Six if (ret) {
785*ab88bd2bSMario Six debug("%s: Could not get reset-GPIO (err = %d)\n",
786*ab88bd2bSMario Six dev->name, ret);
787*ab88bd2bSMario Six return ret;
788*ab88bd2bSMario Six }
789*ab88bd2bSMario Six
790*ab88bd2bSMario Six if (!priv->reset_gpio.dev) {
791*ab88bd2bSMario Six debug("%s: Could not get reset-GPIO\n", dev->name);
792*ab88bd2bSMario Six return -ENOENT;
793*ab88bd2bSMario Six }
794*ab88bd2bSMario Six
795*ab88bd2bSMario Six ret = gpio_request_by_name(dev, "done-gpios", 0, &priv->done_gpio,
796*ab88bd2bSMario Six GPIOD_IS_IN);
797*ab88bd2bSMario Six if (ret) {
798*ab88bd2bSMario Six debug("%s: Could not get done-GPIO (err = %d)\n",
799*ab88bd2bSMario Six dev->name, ret);
800*ab88bd2bSMario Six return ret;
801*ab88bd2bSMario Six }
802*ab88bd2bSMario Six
803*ab88bd2bSMario Six if (!priv->done_gpio.dev) {
804*ab88bd2bSMario Six debug("%s: Could not get done-GPIO\n", dev->name);
805*ab88bd2bSMario Six return -ENOENT;
806*ab88bd2bSMario Six }
807*ab88bd2bSMario Six
808*ab88bd2bSMario Six ret = dm_gpio_set_value(&priv->reset_gpio, 1);
809*ab88bd2bSMario Six if (ret) {
810*ab88bd2bSMario Six debug("%s: Error while setting reset-GPIO (err = %d)\n",
811*ab88bd2bSMario Six dev->name, ret);
812*ab88bd2bSMario Six return ret;
813*ab88bd2bSMario Six }
814*ab88bd2bSMario Six
815*ab88bd2bSMario Six /* If FPGA already runs, don't initialize again */
816*ab88bd2bSMario Six if (do_reflection_test(dev))
817*ab88bd2bSMario Six goto reflection_ok;
818*ab88bd2bSMario Six
819*ab88bd2bSMario Six ret = dm_gpio_set_value(&priv->reset_gpio, 0);
820*ab88bd2bSMario Six if (ret) {
821*ab88bd2bSMario Six debug("%s: Error while setting reset-GPIO (err = %d)\n",
822*ab88bd2bSMario Six dev->name, ret);
823*ab88bd2bSMario Six return ret;
824*ab88bd2bSMario Six }
825*ab88bd2bSMario Six
826*ab88bd2bSMario Six ret = wait_for_fpga_done(dev);
827*ab88bd2bSMario Six if (ret) {
828*ab88bd2bSMario Six debug("%s: Error while waiting for FPGA done (err = %d)\n",
829*ab88bd2bSMario Six dev->name, ret);
830*ab88bd2bSMario Six return ret;
831*ab88bd2bSMario Six }
832*ab88bd2bSMario Six
833*ab88bd2bSMario Six udelay(10);
834*ab88bd2bSMario Six
835*ab88bd2bSMario Six ret = dm_gpio_set_value(&priv->reset_gpio, 1);
836*ab88bd2bSMario Six if (ret) {
837*ab88bd2bSMario Six debug("%s: Error while setting reset-GPIO (err = %d)\n",
838*ab88bd2bSMario Six dev->name, ret);
839*ab88bd2bSMario Six return ret;
840*ab88bd2bSMario Six }
841*ab88bd2bSMario Six
842*ab88bd2bSMario Six if (!do_reflection_test(dev)) {
843*ab88bd2bSMario Six debug("%s: Reflection test FAILED\n", dev->name);
844*ab88bd2bSMario Six return -EIO;
845*ab88bd2bSMario Six }
846*ab88bd2bSMario Six
847*ab88bd2bSMario Six reflection_ok:
848*ab88bd2bSMario Six printf("%s: Reflection test passed.\n", dev->name);
849*ab88bd2bSMario Six
850*ab88bd2bSMario Six fpga_print_info(dev);
851*ab88bd2bSMario Six
852*ab88bd2bSMario Six return 0;
853*ab88bd2bSMario Six }
854*ab88bd2bSMario Six
855*ab88bd2bSMario Six static const struct udevice_id ihs_fpga_ids[] = {
856*ab88bd2bSMario Six { .compatible = "gdsys,iocon_fpga" },
857*ab88bd2bSMario Six { .compatible = "gdsys,iocpu_fpga" },
858*ab88bd2bSMario Six { }
859*ab88bd2bSMario Six };
860*ab88bd2bSMario Six
861*ab88bd2bSMario Six U_BOOT_DRIVER(ihs_fpga_bus) = {
862*ab88bd2bSMario Six .name = "ihs_fpga_bus",
863*ab88bd2bSMario Six .id = UCLASS_MISC,
864*ab88bd2bSMario Six .of_match = ihs_fpga_ids,
865*ab88bd2bSMario Six .probe = ihs_fpga_probe,
866*ab88bd2bSMario Six .priv_auto_alloc_size = sizeof(struct ihs_fpga_priv),
867*ab88bd2bSMario Six };
868