uboot/board/gdsys/common/mclink.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2012
   4 * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
   5 */
   6
   7#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
   8
   9#include <common.h>
  10#include <asm/io.h>
  11#include <errno.h>
  12
  13#include <gdsys_fpga.h>
  14
  15enum {
  16        MCINT_SLAVE_LINK_CHANGED_EV = 1 << 7,
  17        MCINT_TX_ERROR_EV = 1 << 9,
  18        MCINT_TX_BUFFER_FREE = 1 << 10,
  19        MCINT_TX_PACKET_TRANSMITTED_EV = 1 << 11,
  20        MCINT_RX_ERROR_EV = 1 << 13,
  21        MCINT_RX_CONTENT_AVAILABLE = 1 << 14,
  22        MCINT_RX_PACKET_RECEIVED_EV = 1 << 15,
  23};
  24
  25int mclink_probe(void)
  26{
  27        unsigned int k;
  28        int slaves = 0;
  29
  30        for (k = 0; k < CONFIG_SYS_MCLINK_MAX; ++k) {
  31                int timeout = 0;
  32                unsigned int ctr = 0;
  33                u16 mc_status;
  34
  35                FPGA_GET_REG(k, mc_status, &mc_status);
  36
  37                if (!(mc_status & (1 << 15)))
  38                        break;
  39
  40                FPGA_SET_REG(k, mc_control, 0x8000);
  41
  42                FPGA_GET_REG(k, mc_status, &mc_status);
  43                while (!(mc_status & (1 << 14))) {
  44                        udelay(100);
  45                        if (ctr++ > 500) {
  46                                timeout = 1;
  47                                break;
  48                        }
  49                        FPGA_GET_REG(k, mc_status, &mc_status);
  50                }
  51                if (timeout)
  52                        break;
  53
  54                printf("waited %d us for mclink %d to come up\n", ctr * 100, k);
  55
  56                slaves++;
  57        }
  58
  59        return slaves;
  60}
  61
  62int mclink_send(u8 slave, u16 addr, u16 data)
  63{
  64        unsigned int ctr = 0;
  65        u16 int_status;
  66        u16 rx_cmd_status;
  67        u16 rx_cmd;
  68
  69        /* reset interrupt status */
  70        FPGA_GET_REG(0, mc_int, &int_status);
  71        FPGA_SET_REG(0, mc_int, int_status);
  72
  73        /* send */
  74        FPGA_SET_REG(0, mc_tx_address, addr);
  75        FPGA_SET_REG(0, mc_tx_data, data);
  76        FPGA_SET_REG(0, mc_tx_cmd, (slave & 0x03) << 14);
  77        FPGA_SET_REG(0, mc_control, 0x8001);
  78
  79        /* wait for reply */
  80        FPGA_GET_REG(0, mc_int, &int_status);
  81        while (!(int_status & MCINT_RX_PACKET_RECEIVED_EV)) {
  82                udelay(100);
  83                if (ctr++ > 3)
  84                        return -ETIMEDOUT;
  85                FPGA_GET_REG(0, mc_int, &int_status);
  86        }
  87
  88        FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status);
  89        rx_cmd = (rx_cmd_status >> 12) & 0x03;
  90        if (rx_cmd != 0)
  91                printf("mclink_send: received cmd %d, expected %d\n", rx_cmd,
  92                       0);
  93
  94        return 0;
  95}
  96
  97int mclink_receive(u8 slave, u16 addr, u16 *data)
  98{
  99        u16 rx_cmd_status;
 100        u16 rx_cmd;
 101        u16 int_status;
 102        unsigned int ctr = 0;
 103
 104        /* send read request */
 105        FPGA_SET_REG(0, mc_tx_address, addr);
 106        FPGA_SET_REG(0, mc_tx_cmd,
 107                     ((slave & 0x03) << 14) | (1 << 12) | (1 << 0));
 108        FPGA_SET_REG(0, mc_control, 0x8001);
 109
 110
 111        /* wait for reply */
 112        FPGA_GET_REG(0, mc_int, &int_status);
 113        while (!(int_status & MCINT_RX_CONTENT_AVAILABLE)) {
 114                udelay(100);
 115                if (ctr++ > 3)
 116                        return -ETIMEDOUT;
 117                FPGA_GET_REG(0, mc_int, &int_status);
 118        }
 119
 120        /* check reply */
 121        FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status);
 122        if ((rx_cmd_status >> 14) != slave) {
 123                printf("mclink_receive: reply from slave %d, expected %d\n",
 124                       rx_cmd_status >> 14, slave);
 125                return -EINVAL;
 126        }
 127
 128        rx_cmd = (rx_cmd_status >> 12) & 0x03;
 129        if (rx_cmd != 1) {
 130                printf("mclink_send: received cmd %d, expected %d\n",
 131                       rx_cmd, 1);
 132                return -EIO;
 133        }
 134
 135        FPGA_GET_REG(0, mc_rx_data, data);
 136
 137        return 0;
 138}
 139
 140#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
 141