uboot/board/gdsys/405ep/iocon.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <command.h>
  10#include <errno.h>
  11#include <asm/processor.h>
  12#include <asm/io.h>
  13#include <asm/ppc4xx-gpio.h>
  14
  15#include "405ep.h"
  16#include <gdsys_fpga.h>
  17
  18#include "../common/osd.h"
  19#include "../common/mclink.h"
  20#include "../common/phy.h"
  21
  22#include <i2c.h>
  23#include <pca953x.h>
  24#include <pca9698.h>
  25
  26#include <miiphy.h>
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30#define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
  31#define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
  32#define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)
  33
  34#define MAX_MUX_CHANNELS 2
  35
  36enum {
  37        UNITTYPE_MAIN_SERVER = 0,
  38        UNITTYPE_MAIN_USER = 1,
  39        UNITTYPE_VIDEO_SERVER = 2,
  40        UNITTYPE_VIDEO_USER = 3,
  41};
  42
  43enum {
  44        HWVER_100 = 0,
  45        HWVER_104 = 1,
  46        HWVER_110 = 2,
  47        HWVER_120 = 3,
  48        HWVER_200 = 4,
  49        HWVER_210 = 5,
  50        HWVER_220 = 6,
  51        HWVER_230 = 7,
  52};
  53
  54enum {
  55        FPGA_HWVER_200 = 0,
  56        FPGA_HWVER_210 = 1,
  57};
  58
  59enum {
  60        COMPRESSION_NONE = 0,
  61        COMPRESSION_TYPE1_DELTA = 1,
  62        COMPRESSION_TYPE1_TYPE2_DELTA = 3,
  63};
  64
  65enum {
  66        AUDIO_NONE = 0,
  67        AUDIO_TX = 1,
  68        AUDIO_RX = 2,
  69        AUDIO_RXTX = 3,
  70};
  71
  72enum {
  73        SYSCLK_147456 = 0,
  74};
  75
  76enum {
  77        RAM_DDR2_32 = 0,
  78        RAM_DDR3_32 = 1,
  79};
  80
  81enum {
  82        CARRIER_SPEED_1G = 0,
  83        CARRIER_SPEED_2_5G = 1,
  84};
  85
  86enum {
  87        MCFPGA_DONE = 1 << 0,
  88        MCFPGA_INIT_N = 1 << 1,
  89        MCFPGA_PROGRAM_N = 1 << 2,
  90        MCFPGA_UPDATE_ENABLE_N = 1 << 3,
  91        MCFPGA_RESET_N = 1 << 4,
  92};
  93
  94enum {
  95        GPIO_MDC = 1 << 14,
  96        GPIO_MDIO = 1 << 15,
  97};
  98
  99unsigned int mclink_fpgacount;
 100struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
 101
 102int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
 103{
 104        int res;
 105
 106        switch (fpga) {
 107        case 0:
 108                out_le16(reg, data);
 109                break;
 110        default:
 111                res = mclink_send(fpga - 1, regoff, data);
 112                if (res < 0) {
 113                        printf("mclink_send reg %02lx data %04x returned %d\n",
 114                               regoff, data, res);
 115                        return res;
 116                }
 117                break;
 118        }
 119
 120        return 0;
 121}
 122
 123int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
 124{
 125        int res;
 126
 127        switch (fpga) {
 128        case 0:
 129                *data = in_le16(reg);
 130                break;
 131        default:
 132                if (fpga > mclink_fpgacount)
 133                        return -EINVAL;
 134                res = mclink_receive(fpga - 1, regoff, data);
 135                if (res < 0) {
 136                        printf("mclink_receive reg %02lx returned %d\n",
 137                               regoff, res);
 138                        return res;
 139                }
 140        }
 141
 142        return 0;
 143}
 144
 145/*
 146 * Check Board Identity:
 147 */
 148int checkboard(void)
 149{
 150        char *s = getenv("serial#");
 151
 152        puts("Board: ");
 153
 154        puts("IoCon");
 155
 156        if (s != NULL) {
 157                puts(", serial# ");
 158                puts(s);
 159        }
 160
 161        puts("\n");
 162
 163        return 0;
 164}
 165
 166static void print_fpga_info(unsigned int fpga, bool rgmii2_present)
 167{
 168        u16 versions;
 169        u16 fpga_version;
 170        u16 fpga_features;
 171        unsigned unit_type;
 172        unsigned hardware_version;
 173        unsigned feature_compression;
 174        unsigned feature_osd;
 175        unsigned feature_audio;
 176        unsigned feature_sysclock;
 177        unsigned feature_ramconfig;
 178        unsigned feature_carrier_speed;
 179        unsigned feature_carriers;
 180        unsigned feature_video_channels;
 181
 182        int legacy = get_fpga_state(fpga) & FPGA_STATE_PLATFORM;
 183
 184        FPGA_GET_REG(fpga, versions, &versions);
 185        FPGA_GET_REG(fpga, fpga_version, &fpga_version);
 186        FPGA_GET_REG(fpga, fpga_features, &fpga_features);
 187
 188        unit_type = (versions & 0xf000) >> 12;
 189        feature_compression = (fpga_features & 0xe000) >> 13;
 190        feature_osd = fpga_features & (1<<11);
 191        feature_audio = (fpga_features & 0x0600) >> 9;
 192        feature_sysclock = (fpga_features & 0x0180) >> 7;
 193        feature_ramconfig = (fpga_features & 0x0060) >> 5;
 194        feature_carrier_speed = fpga_features & (1<<4);
 195        feature_carriers = (fpga_features & 0x000c) >> 2;
 196        feature_video_channels = fpga_features & 0x0003;
 197
 198        if (legacy)
 199                printf("legacy ");
 200
 201        switch (unit_type) {
 202        case UNITTYPE_MAIN_USER:
 203                printf("Mainchannel");
 204                break;
 205
 206        case UNITTYPE_VIDEO_USER:
 207                printf("Videochannel");
 208                break;
 209
 210        default:
 211                printf("UnitType %d(not supported)", unit_type);
 212                break;
 213        }
 214
 215        if (unit_type == UNITTYPE_MAIN_USER) {
 216                if (legacy)
 217                        hardware_version =
 218                                (in_le16((void *)LATCH2_BASE)>>8) & 0x0f;
 219                else
 220                        hardware_version =
 221                                  (!!pca9698_get_value(0x20, 24) << 0)
 222                                | (!!pca9698_get_value(0x20, 25) << 1)
 223                                | (!!pca9698_get_value(0x20, 26) << 2)
 224                                | (!!pca9698_get_value(0x20, 27) << 3);
 225                switch (hardware_version) {
 226                case HWVER_100:
 227                        printf(" HW-Ver 1.00,");
 228                        break;
 229
 230                case HWVER_104:
 231                        printf(" HW-Ver 1.04,");
 232                        break;
 233
 234                case HWVER_110:
 235                        printf(" HW-Ver 1.10,");
 236                        break;
 237
 238                case HWVER_120:
 239                        printf(" HW-Ver 1.20-1.21,");
 240                        break;
 241
 242                case HWVER_200:
 243                        printf(" HW-Ver 2.00,");
 244                        break;
 245
 246                case HWVER_210:
 247                        printf(" HW-Ver 2.10,");
 248                        break;
 249
 250                case HWVER_220:
 251                        printf(" HW-Ver 2.20,");
 252                        break;
 253
 254                case HWVER_230:
 255                        printf(" HW-Ver 2.30,");
 256                        break;
 257
 258                default:
 259                        printf(" HW-Ver %d(not supported),",
 260                               hardware_version);
 261                        break;
 262                }
 263                if (rgmii2_present)
 264                        printf(" RGMII2,");
 265        }
 266
 267        if (unit_type == UNITTYPE_VIDEO_USER) {
 268                hardware_version = versions & 0x000f;
 269                switch (hardware_version) {
 270                case FPGA_HWVER_200:
 271                        printf(" HW-Ver 2.00,");
 272                        break;
 273
 274                case FPGA_HWVER_210:
 275                        printf(" HW-Ver 2.10,");
 276                        break;
 277
 278                default:
 279                        printf(" HW-Ver %d(not supported),",
 280                               hardware_version);
 281                        break;
 282                }
 283        }
 284
 285        printf(" FPGA V %d.%02d\n       features:",
 286               fpga_version / 100, fpga_version % 100);
 287
 288
 289        switch (feature_compression) {
 290        case COMPRESSION_NONE:
 291                printf(" no compression");
 292                break;
 293
 294        case COMPRESSION_TYPE1_DELTA:
 295                printf(" type1-deltacompression");
 296                break;
 297
 298        case COMPRESSION_TYPE1_TYPE2_DELTA:
 299                printf(" type1-deltacompression, type2-inlinecompression");
 300                break;
 301
 302        default:
 303                printf(" compression %d(not supported)", feature_compression);
 304                break;
 305        }
 306
 307        printf(", %sosd", feature_osd ? "" : "no ");
 308
 309        switch (feature_audio) {
 310        case AUDIO_NONE:
 311                printf(", no audio");
 312                break;
 313
 314        case AUDIO_TX:
 315                printf(", audio tx");
 316                break;
 317
 318        case AUDIO_RX:
 319                printf(", audio rx");
 320                break;
 321
 322        case AUDIO_RXTX:
 323                printf(", audio rx+tx");
 324                break;
 325
 326        default:
 327                printf(", audio %d(not supported)", feature_audio);
 328                break;
 329        }
 330
 331        puts(",\n       ");
 332
 333        switch (feature_sysclock) {
 334        case SYSCLK_147456:
 335                printf("clock 147.456 MHz");
 336                break;
 337
 338        default:
 339                printf("clock %d(not supported)", feature_sysclock);
 340                break;
 341        }
 342
 343        switch (feature_ramconfig) {
 344        case RAM_DDR2_32:
 345                printf(", RAM 32 bit DDR2");
 346                break;
 347
 348        case RAM_DDR3_32:
 349                printf(", RAM 32 bit DDR3");
 350                break;
 351
 352        default:
 353                printf(", RAM %d(not supported)", feature_ramconfig);
 354                break;
 355        }
 356
 357        printf(", %d carrier(s) %s", feature_carriers,
 358               feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
 359
 360        printf(", %d video channel(s)\n", feature_video_channels);
 361}
 362
 363int last_stage_init(void)
 364{
 365        int slaves;
 366        unsigned int k;
 367        unsigned int mux_ch;
 368        unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 };
 369        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 370        u16 fpga_features;
 371        int feature_carrier_speed;
 372        bool ch0_rgmii2_present = false;
 373
 374        FPGA_GET_REG(0, fpga_features, &fpga_features);
 375        feature_carrier_speed = fpga_features & (1<<4);
 376
 377        if (!legacy) {
 378                /* Turn on Parade DP501 */
 379                pca9698_direction_output(0x20, 9, 1);
 380
 381                ch0_rgmii2_present = !pca9698_get_value(0x20, 30);
 382        }
 383
 384        /* wait for FPGA done; then reset FPGA */
 385        for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
 386                unsigned int ctr = 0;
 387
 388                if (i2c_probe(mclink_controllers[k]))
 389                        continue;
 390
 391                while (!(pca953x_get_val(mclink_controllers[k])
 392                       & MCFPGA_DONE)) {
 393                        udelay(100000);
 394                        if (ctr++ > 5) {
 395                                printf("no done for mclink_controller %d\n", k);
 396                                break;
 397                        }
 398                }
 399
 400                pca953x_set_dir(mclink_controllers[k], MCFPGA_RESET_N, 0);
 401                pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N, 0);
 402                udelay(10);
 403                pca953x_set_val(mclink_controllers[k], MCFPGA_RESET_N,
 404                                MCFPGA_RESET_N);
 405        }
 406
 407        if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) {
 408                int retval;
 409                struct mii_dev *mdiodev = mdio_alloc();
 410                if (!mdiodev)
 411                        return -ENOMEM;
 412                strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
 413                mdiodev->read = bb_miiphy_read;
 414                mdiodev->write = bb_miiphy_write;
 415
 416                retval = mdio_register(mdiodev);
 417                if (retval < 0)
 418                        return retval;
 419                for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
 420                        if ((mux_ch == 1) && !ch0_rgmii2_present)
 421                                continue;
 422
 423                        setup_88e1518(bb_miiphy_buses[0].name, mux_ch);
 424                }
 425        }
 426
 427        /* give slave-PLLs and Parade DP501 some time to be up and running */
 428        udelay(500000);
 429
 430        mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
 431        slaves = mclink_probe();
 432        mclink_fpgacount = 0;
 433
 434        print_fpga_info(0, ch0_rgmii2_present);
 435        osd_probe(0);
 436
 437        if (slaves <= 0)
 438                return 0;
 439
 440        mclink_fpgacount = slaves;
 441
 442        for (k = 1; k <= slaves; ++k) {
 443                FPGA_GET_REG(k, fpga_features, &fpga_features);
 444                feature_carrier_speed = fpga_features & (1<<4);
 445
 446                print_fpga_info(k, false);
 447                osd_probe(k);
 448                if (feature_carrier_speed == CARRIER_SPEED_1G) {
 449                        int retval;
 450                        struct mii_dev *mdiodev = mdio_alloc();
 451                        if (!mdiodev)
 452                                return -ENOMEM;
 453                        strncpy(mdiodev->name, bb_miiphy_buses[k].name,
 454                                MDIO_NAME_LEN);
 455                        mdiodev->read = bb_miiphy_read;
 456                        mdiodev->write = bb_miiphy_write;
 457
 458                        retval = mdio_register(mdiodev);
 459                        if (retval < 0)
 460                                return retval;
 461                        setup_88e1518(bb_miiphy_buses[k].name, 0);
 462                }
 463        }
 464
 465        return 0;
 466}
 467
 468/*
 469 * provide access to fpga gpios (for I2C bitbang)
 470 * (these may look all too simple but make iocon.h much more readable)
 471 */
 472void fpga_gpio_set(unsigned int bus, int pin)
 473{
 474        FPGA_SET_REG(bus, gpio.set, pin);
 475}
 476
 477void fpga_gpio_clear(unsigned int bus, int pin)
 478{
 479        FPGA_SET_REG(bus, gpio.clear, pin);
 480}
 481
 482int fpga_gpio_get(unsigned int bus, int pin)
 483{
 484        u16 val;
 485
 486        FPGA_GET_REG(bus, gpio.read, &val);
 487
 488        return val & pin;
 489}
 490
 491void gd405ep_init(void)
 492{
 493        unsigned int k;
 494
 495        if (i2c_probe(0x20)) { /* i2c_probe returns 0 on success */
 496                for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
 497                        gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
 498        } else {
 499                pca9698_direction_output(0x20, 4, 1);
 500        }
 501}
 502
 503void gd405ep_set_fpga_reset(unsigned state)
 504{
 505        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 506
 507        if (legacy) {
 508                if (state) {
 509                        out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
 510                        out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
 511                } else {
 512                        out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
 513                        out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
 514                }
 515        } else {
 516                pca9698_set_value(0x20, 4, state ? 0 : 1);
 517        }
 518}
 519
 520void gd405ep_setup_hw(void)
 521{
 522        /*
 523         * set "startup-finished"-gpios
 524         */
 525        gpio_write_bit(21, 0);
 526        gpio_write_bit(22, 1);
 527}
 528
 529int gd405ep_get_fpga_done(unsigned fpga)
 530{
 531        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 532
 533        if (legacy)
 534                return in_le16((void *)LATCH2_BASE)
 535                       & CONFIG_SYS_FPGA_DONE(fpga);
 536        else
 537                return pca9698_get_value(0x20, 20);
 538}
 539
 540/*
 541 * FPGA MII bitbang implementation
 542 */
 543
 544struct fpga_mii {
 545        unsigned fpga;
 546        int mdio;
 547} fpga_mii[] = {
 548        { 0, 1},
 549        { 1, 1},
 550        { 2, 1},
 551        { 3, 1},
 552};
 553
 554static int mii_dummy_init(struct bb_miiphy_bus *bus)
 555{
 556        return 0;
 557}
 558
 559static int mii_mdio_active(struct bb_miiphy_bus *bus)
 560{
 561        struct fpga_mii *fpga_mii = bus->priv;
 562
 563        if (fpga_mii->mdio)
 564                FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
 565        else
 566                FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
 567
 568        return 0;
 569}
 570
 571static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
 572{
 573        struct fpga_mii *fpga_mii = bus->priv;
 574
 575        FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
 576
 577        return 0;
 578}
 579
 580static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
 581{
 582        struct fpga_mii *fpga_mii = bus->priv;
 583
 584        if (v)
 585                FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
 586        else
 587                FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
 588
 589        fpga_mii->mdio = v;
 590
 591        return 0;
 592}
 593
 594static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
 595{
 596        u16 gpio;
 597        struct fpga_mii *fpga_mii = bus->priv;
 598
 599        FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
 600
 601        *v = ((gpio & GPIO_MDIO) != 0);
 602
 603        return 0;
 604}
 605
 606static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
 607{
 608        struct fpga_mii *fpga_mii = bus->priv;
 609
 610        if (v)
 611                FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
 612        else
 613                FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
 614
 615        return 0;
 616}
 617
 618static int mii_delay(struct bb_miiphy_bus *bus)
 619{
 620        udelay(1);
 621
 622        return 0;
 623}
 624
 625struct bb_miiphy_bus bb_miiphy_buses[] = {
 626        {
 627                .name = "board0",
 628                .init = mii_dummy_init,
 629                .mdio_active = mii_mdio_active,
 630                .mdio_tristate = mii_mdio_tristate,
 631                .set_mdio = mii_set_mdio,
 632                .get_mdio = mii_get_mdio,
 633                .set_mdc = mii_set_mdc,
 634                .delay = mii_delay,
 635                .priv = &fpga_mii[0],
 636        },
 637        {
 638                .name = "board1",
 639                .init = mii_dummy_init,
 640                .mdio_active = mii_mdio_active,
 641                .mdio_tristate = mii_mdio_tristate,
 642                .set_mdio = mii_set_mdio,
 643                .get_mdio = mii_get_mdio,
 644                .set_mdc = mii_set_mdc,
 645                .delay = mii_delay,
 646                .priv = &fpga_mii[1],
 647        },
 648        {
 649                .name = "board2",
 650                .init = mii_dummy_init,
 651                .mdio_active = mii_mdio_active,
 652                .mdio_tristate = mii_mdio_tristate,
 653                .set_mdio = mii_set_mdio,
 654                .get_mdio = mii_get_mdio,
 655                .set_mdc = mii_set_mdc,
 656                .delay = mii_delay,
 657                .priv = &fpga_mii[2],
 658        },
 659        {
 660                .name = "board3",
 661                .init = mii_dummy_init,
 662                .mdio_active = mii_mdio_active,
 663                .mdio_tristate = mii_mdio_tristate,
 664                .set_mdio = mii_set_mdio,
 665                .get_mdio = mii_get_mdio,
 666                .set_mdc = mii_set_mdc,
 667                .delay = mii_delay,
 668                .priv = &fpga_mii[3],
 669        },
 670};
 671
 672int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
 673                          sizeof(bb_miiphy_buses[0]);
 674