Загрузка данных
#define SYSCONFIG_I2C_ACTIVATION_KEY {0xA4, 0xC6, 0xF4, 0x8A}
#define SYSCONFIG_ISC_ENABLE {0xC6, 0x00, 0x00, 0x00}
#define SYSCONFIG_ISC_DISABLE {0x26, 0x00, 0x00, 0x00}
#define SYSCONFIG_ISC_ERASE {0x0E, 0x01, 0x00, 0x00}
#define SYSCONFIG_LSC_READ_STATUS {0x3C, 0x00, 0x00, 0x00}
#define SYSCONFIG_LSC_CHECK_BUSY {0xF0, 0x00, 0x00, 0x00}
#define SYSCONFIG_LSC_REFRESH {0x79, 0x00, 0x00, 0x00}
#define SYSCONFIG_LSC_INIT_ADDR {0x46, 0x00, 0x00, 0x00}
#define SYSCONFIG_LSC_BITSTREAM_BURST {0x7a, 0x00, 0x00, 0x00}
#define SYSCONFIG_STATUS_DONE BIT(8)
#define SYSCONFIG_STATUS_BUSY BIT(12)
#define SYSCONFIG_STATUS_FAIL BIT(13)
#define SYSCONFIG_STATUS_ERR GENMASK(25, 23)
static int sysconfig_lsc_refresh(struct sysconfig_priv *priv)
{
static const u8 lsc_refresh[] = SYSCONFIG_LSC_REFRESH;
int ret;
ret = sysconfig_cmd_write(priv, lsc_refresh, sizeof(lsc_refresh));
if (ret)
return ret;
usleep_range(4000, 8000);
return 0;
}
static int sysconfig_activation_key(struct sysconfig_priv *priv)
{
u8 activation_key[] = SYSCONFIG_I2C_ACTIVATION_KEY;
int ret;
ret = sysconfig_cmd_write(priv, activation_key, sizeof(activation_key));
if (ret)
return ret;
return 0;
}
static int sysconfig_isc_init(struct sysconfig_priv *priv)
{
int ret = sysconfig_isc_enable(priv);
if (ret)
return ret;
return sysconfig_isc_erase(priv);
}
static int sysconfig_isc_enable(struct sysconfig_priv *priv)
{
u8 isc_enable[] = SYSCONFIG_ISC_ENABLE;
u64 status;
int ret;
ret = sysconfig_cmd_write(priv, isc_enable, sizeof(isc_enable));
if (ret)
return ret;
ret = sysconfig_poll_status(priv, &status);
if (ret)
return ret;
if (status & SYSCONFIG_STATUS_FAIL)
return -EFAULT;
return 0;
}
static int sysconfig_isc_erase(struct sysconfig_priv *priv)
{
u8 isc_erase[] = SYSCONFIG_ISC_ERASE;
u64 status;
int ret;
ret = sysconfig_cmd_write(priv, isc_erase, sizeof(isc_erase));
if (ret)
return ret;
ret = sysconfig_poll_status(priv, &status);
if (ret)
return ret;
if (status & SYSCONFIG_STATUS_FAIL)
return -EFAULT;
return 0;
}
static int sysconfig_lsc_init_addr(struct sysconfig_priv *priv)
{
const u8 lsc_init_addr[] = SYSCONFIG_LSC_INIT_ADDR;
return sysconfig_cmd_write(priv, lsc_init_addr, sizeof(lsc_init_addr));
}
static int sysconfig_refresh(struct sysconfig_priv *priv)
{
struct gpio_desc *program = priv->program;
struct gpio_desc *init = priv->init;
struct gpio_desc *done = priv->done;
if (program && init && done)
return sysconfig_gpio_refresh(priv);
return sysconfig_lsc_refresh(priv);
}
static int sysconfig_burst_write_init(struct sysconfig_priv *priv)
{
return priv->bitstream_burst_write_init(priv);
}
static int sysconfig_burst_write_complete(struct sysconfig_priv *priv)
{
return priv->bitstream_burst_write_complete(priv);
}
static int sysconfig_bitstream_burst_write(struct sysconfig_priv *priv, const char *buf, size_t count)
{
int ret = priv->bitstream_burst_write(priv, buf, count);
if (ret)
sysconfig_burst_write_complete(priv);
return ret;
}
static int sysconfig_ops_write_init(struct fpga_manager *mgr, struct fpga_image_info *info, const char *buf, size_t count)
{
struct sysconfig_priv *priv = mgr->priv;
struct device *dev = &mgr->dev;
int ret;
if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
dev_err(dev, "Partial reconfiguration is not supported\n");
return -EOPNOTSUPP;
}
/* Enter program mode */
ret = sysconfig_refresh(priv);
if (ret) {
dev_err(dev, "Failed to go to program mode\n");
return ret;
}
ret = sysconfig_activation_key(priv);
if (ret) {
dev_err(dev, "Failed set activation key\n");
return ret;
}
/* Enter ISC mode */
ret = sysconfig_isc_init(priv);
if (ret) {
dev_err(dev, "Failed to go to ISC mode\n");
return ret;
}
/* Initialize the Address Shift Register */
ret = sysconfig_lsc_init_addr(priv);
if (ret) {
dev_err(dev,
"Failed to initialize the Address Shift Register\n");
return ret;
}
/* Prepare for bitstream burst write */
ret = sysconfig_burst_write_init(priv);
if (ret)
dev_err(dev, "Failed to prepare for bitstream burst write\n");
return ret;
}