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