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