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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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