Загрузка данных


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;
}