static int sysconfig_isc_finish(struct sysconfig_priv *priv)
{
struct gpio_desc *done_gpio = priv->done;
u64 status;
int ret;
printk("%s(%d) done_gpio=%p\n", __FUNCTION__, __LINE__, done_gpio);
if (done_gpio) {
ret = sysconfig_poll_status(priv, &status);
printk("%s(%d) ret=%d status=0x%llX\n", __FUNCTION__, __LINE__, ret, status);
if (ret)
return ret;
ret = sysconfig_isc_disable(priv);
if (ret)
return ret;
return sysconfig_poll_gpio(done_gpio, true);
}
printk("%s(%d) [NEXUS HACK] Sending ISC_DISABLE before checking status done\n", __FUNCTION__, __LINE__);
/* 1. Сначала ПРИНУДИТЕЛЬНО отправляем команду ISC_DISABLE (0x26).
* Только после нее ПЛИС Nexus начнет процедуру Wake-up и поднимет DONE. */
ret = sysconfig_isc_disable(priv);
if (ret) {
dev_err(priv->dev, "Failed to send ISC_DISABLE\n");
return ret;
}
/* 2. Даем ПЛИС честные 50 мс на расчет финального CRC и переход в User Mode */
msleep(50);
/* 3. Опрашиваем финальный статус */
ret = sysconfig_poll_status(priv, &status);
printk("%s(%d) Post-Disable Status ret=%d status=0x%llX\n", __FUNCTION__, __LINE__, ret, status);
if (ret)
return ret;
/* 4. Теперь проверяем, успешна ли инициализация */
if ((status & SYSCONFIG_STATUS_DONE) &&
!(status & SYSCONFIG_STATUS_BUSY) &&
!(status & SYSCONFIG_STATUS_ERR)) {
printk("FPGA Nexus programmed successfully! DONE bit is HIGH.\n");
return 0; // ПОБЕДА!
}
dev_err(priv->dev, "FPGA status check failed after ISC_DISABLE\n");
return -EFAULT;
}