// SPDX-License-Identifier: GPL-2.0-only
/*
 * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
 *
 * Copyright (c) 2010, ST-Ericsson
 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
 *
 * Based on:
 * ST-Ericsson UMAC CW1200 driver which is
 * Copyright (c) 2010, ST-Ericsson
 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
 */

#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/firmware.h>

#include "cw1200.h"
#include "fwio.h"
#include "hwio.h"
#include "hwbus.h"
#include "bh.h"

static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
{
	int hw_type = -1;
	u32 silicon_type = (config_reg_val >> 24) & 0x7;
	u32 silicon_vers = (config_reg_val >> 31) & 0x1;

	switch (silicon_type) {
	case 0x00:
		*major_revision = 1;
		hw_type = HIF_9000_SILICON_VERSATILE;
		break;
	case 0x01:
	case 0x02: /* CW1x00 */
	case 0x04: /* CW1x60 */
		*major_revision = silicon_type;
		if (silicon_vers)
			hw_type = HIF_8601_VERSATILE;
		else
			hw_type = HIF_8601_SILICON;
		break;
	default:
		break;
	}

	return hw_type;
}

static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
{
	int ret, block, num_blocks;
	unsigned i;
	u32 val32;
	u32 put = 0, get = 0;
	u8 *buf = NULL;
	const char *fw_path;
	const struct firmware *firmware = NULL;

	/* Macroses are local. */
#define APB_WRITE(reg, val) \
	do { \
		ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
		if (ret < 0) \
			goto exit; \
	} while (0)
#define APB_WRITE2(reg, val) \
	do { \
		ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
		if (ret < 0) \
			goto free_buffer; \
	} while (0)
#define APB_READ(reg, val) \
	do { \
		ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
		if (ret < 0) \
			goto free_buffer; \
	} while (0)
#define REG_WRITE(reg, val) \
	do { \
		ret = cw1200_reg_write_32(priv, (reg), (val)); \
		if (ret < 0) \
			goto exit; \
	} while (0)
#define REG_READ(reg, val) \
	do { \
		ret = cw1200_reg_read_32(priv, (reg), &(val)); \
		if (ret < 0) \
			goto exit; \
	} while (0)

	switch (priv->hw_revision) {
	case CW1200_HW_REV_CUT10:
		fw_path = FIRMWARE_CUT10;
		if (!priv->sdd_path)
			priv->sdd_path = SDD_FILE_10;
		break;
	case CW1200_HW_REV_CUT11:
		fw_path = FIRMWARE_CUT11;
		if (!priv->sdd_path)
			priv->sdd_path = SDD_FILE_11;
		break;
	case CW1200_HW_REV_CUT20:
		fw_path = FIRMWARE_CUT20;
		if (!priv->sdd_path)
			priv->sdd_path = SDD_FILE_20;
		break;
	case CW1200_HW_REV_CUT22:
		fw_path = FIRMWARE_CUT22;
		if (!priv->sdd_path)
			priv->sdd_path = SDD_FILE_22;
		break;
	case CW1X60_HW_REV:
		fw_path = FIRMWARE_CW1X60;
		if (!priv->sdd_path)
			priv->sdd_path = SDD_FILE_CW1X60;
		break;
	default:
		pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
		return -EINVAL;
	}

	/* Initialize common registers */
	APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
	APB_WRITE(DOWNLOAD_PUT_REG, 0);
	APB_WRITE(DOWNLOAD_GET_REG, 0);
	APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
	APB_WRITE(DOWNLOAD_FLAGS_REG, 0);

	/* Write the NOP Instruction */
	REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
	REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);

	/* Release CPU from RESET */
	REG_READ(ST90TDS_CONFIG_REG_ID, val32);
	val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
	REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);

	/* Enable Clock */
	val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
	REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);

	/* Load a firmware file */
	ret = request_firmware(&firmware, fw_path, priv->pdev);
	if (ret) {
		pr_err("Can't load firmware file %s.\n", fw_path);
		goto exit;
	}

	buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
	if (!buf) {
		pr_err("Can't allocate firmware load buffer.\n");
		ret = -ENOMEM;
		goto firmware_release;
	}

	/* Check if the bootloader is ready */
	for (i = 0; i < 100; i += 1 + i / 2) {
		APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
		if (val32 == DOWNLOAD_I_AM_HERE)
			break;
		mdelay(i);
	} /* End of for loop */

	if (val32 != DOWNLOAD_I_AM_HERE) {
		pr_err("Bootloader is not ready.\n");
		ret = -ETIMEDOUT;
		goto free_buffer;
	}

	/* Calculcate number of download blocks */
	num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;

	/* Updating the length in Download Ctrl Area */
	val32 = firmware->size; /* Explicit cast from size_t to u32 */
	APB_WRITE2(DOWNLOAD_IMAGE_SIZE_REG, val32);

	/* Firmware downloading loop */
	for (block = 0; block < num_blocks; block++) {
		size_t tx_size;
		size_t block_size;

		/* check the download status */
		APB_READ(DOWNLOAD_STATUS_REG, val32);
		if (val32 != DOWNLOAD_PENDING) {
			pr_err("Bootloader reported error %d.\n", val32);
			ret = -EIO;
			goto free_buffer;
		}

		/* loop until put - get <= 24K */
		for (i = 0; i < 100; i++) {
			APB_READ(DOWNLOAD_GET_REG, get);
			if ((put - get) <=
			    (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
				break;
			mdelay(i);
		}

		if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
			pr_err("Timeout waiting for FIFO.\n");
			ret = -ETIMEDOUT;
			goto free_buffer;
		}

		/* calculate the block size */
		tx_size = block_size = min_t(size_t, firmware->size - put,
					DOWNLOAD_BLOCK_SIZE);

		memcpy(buf, &firmware->data[put], block_size);
		if (block_size < DOWNLOAD_BLOCK_SIZE) {
			memset(&buf[block_size], 0,
			       DOWNLOAD_BLOCK_SIZE - block_size);
			tx_size = DOWNLOAD_BLOCK_SIZE;
		}

		/* send the block to sram */
		ret = cw1200_apb_write(priv,
			CW1200_APB(DOWNLOAD_FIFO_OFFSET +
				   (put & (DOWNLOAD_FIFO_SIZE - 1))),
			buf, tx_size);
		if (ret < 0) {
			pr_err("Can't write firmware block @ %d!\n",
			       put & (DOWNLOAD_FIFO_SIZE - 1));
			goto free_buffer;
		}

		/* update the put register */
		put += block_size;
		APB_WRITE2(DOWNLOAD_PUT_REG, put);
	} /* End of firmware download loop */

	/* Wait for the download completion */
	for (i = 0; i < 300; i += 1 + i / 2) {
		APB_READ(DOWNLOAD_STATUS_REG, val32);
		if (val32 != DOWNLOAD_PENDING)
			break;
		mdelay(i);
	}
	if (val32 != DOWNLOAD_SUCCESS) {
		pr_err("Wait for download completion failed: 0x%.8X\n", val32);
		ret = -ETIMEDOUT;
		goto free_buffer;
	} else {
		pr_info("Firmware download completed.\n");
		ret = 0;
	}

free_buffer:
	kfree(buf);
firmware_release:
	release_firmware(firmware);
exit:
	return ret;

#undef APB_WRITE
#undef APB_WRITE2
#undef APB_READ
#undef REG_WRITE
#undef REG_READ
}


static int config_reg_read(struct cw1200_common *priv, u32 *val)
{
	switch (priv->hw_type) {
	case HIF_9000_SILICON_VERSATILE: {
		u16 val16;
		int ret = cw1200_reg_read_16(priv,
					     ST90TDS_CONFIG_REG_ID,
					     &val16);
		if (ret < 0)
			return ret;
		*val = val16;
		return 0;
	}
	case HIF_8601_VERSATILE:
	case HIF_8601_SILICON:
	default:
		cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
		break;
	}
	return 0;
}

static int config_reg_write(struct cw1200_common *priv, u32 val)
{
	switch (priv->hw_type) {
	case HIF_9000_SILICON_VERSATILE:
		return cw1200_reg_write_16(priv,
					   ST90TDS_CONFIG_REG_ID,
					   (u16)val);
	case HIF_8601_VERSATILE:
	case HIF_8601_SILICON:
	default:
		return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
	}
	return 0;
}

int cw1200_load_firmware(struct cw1200_common *priv)
{
	int ret;
	int i;
	u32 val32;
	u16 val16;
	int major_revision = -1;

	/* Read CONFIG Register */
	ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
	if (ret < 0) {
		pr_err("Can't read config register.\n");
		goto out;
	}

	if (val32 == 0 || val32 == 0xffffffff) {
		pr_err("Bad config register value (0x%08x)\n", val32);
		ret = -EIO;
		goto out;
	}

	priv->hw_type = cw1200_get_hw_type(val32, &major_revision);
	if (priv->hw_type < 0) {
		pr_err("Can't deduce hardware type.\n");
		ret = -ENOTSUPP;
		goto out;
	}

	/* Set DPLL Reg value, and read back to confirm writes work */
	ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
				  cw1200_dpll_from_clk(priv->hw_refclk));
	if (ret < 0) {
		pr_err("Can't write DPLL register.\n");
		goto out;
	}

	msleep(20);

	ret = cw1200_reg_read_32(priv,
		ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
	if (ret < 0) {
		pr_err("Can't read DPLL register.\n");
		goto out;
	}

	if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
		pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
		       cw1200_dpll_from_clk(priv->hw_refclk), val32);
		ret = -EIO;
		goto out;
	}

	/* Set wakeup bit in device */
	ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
	if (ret < 0) {
		pr_err("set_wakeup: can't read control register.\n");
		goto out;
	}

	ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
		val16 | ST90TDS_CONT_WUP_BIT);
	if (ret < 0) {
		pr_err("set_wakeup: can't write control register.\n");
		goto out;
	}

	/* Wait for wakeup */
	for (i = 0; i < 300; i += (1 + i / 2)) {
		ret = cw1200_reg_read_16(priv,
			ST90TDS_CONTROL_REG_ID, &val16);
		if (ret < 0) {
			pr_err("wait_for_wakeup: can't read control register.\n");
			goto out;
		}

		if (val16 & ST90TDS_CONT_RDY_BIT)
			break;

		msleep(i);
	}

	if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
		pr_err("wait_for_wakeup: device is not responding.\n");
		ret = -ETIMEDOUT;
		goto out;
	}

	switch (major_revision) {
	case 1:
		/* CW1200 Hardware detection logic : Check for CUT1.1 */
		ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
		if (ret) {
			pr_err("HW detection: can't read CUT ID.\n");
			goto out;
		}

		switch (val32) {
		case CW1200_CUT_11_ID_STR:
			pr_info("CW1x00 Cut 1.1 silicon detected.\n");
			priv->hw_revision = CW1200_HW_REV_CUT11;
			break;
		default:
			pr_info("CW1x00 Cut 1.0 silicon detected.\n");
			priv->hw_revision = CW1200_HW_REV_CUT10;
			break;
		}

		/* According to ST-E, CUT<2.0 has busted BA TID0-3.
		   Just disable it entirely...
		*/
		priv->ba_rx_tid_mask = 0;
		priv->ba_tx_tid_mask = 0;
		break;
	case 2: {
		u32 ar1, ar2, ar3;
		ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
		if (ret) {
			pr_err("(1) HW detection: can't read CUT ID\n");
			goto out;
		}
		ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
		if (ret) {
			pr_err("(2) HW detection: can't read CUT ID.\n");
			goto out;
		}

		ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
		if (ret) {
			pr_err("(3) HW detection: can't read CUT ID.\n");
			goto out;
		}

		if (ar1 == CW1200_CUT_22_ID_STR1 &&
		    ar2 == CW1200_CUT_22_ID_STR2 &&
		    ar3 == CW1200_CUT_22_ID_STR3) {
			pr_info("CW1x00 Cut 2.2 silicon detected.\n");
			priv->hw_revision = CW1200_HW_REV_CUT22;
		} else {
			pr_info("CW1x00 Cut 2.0 silicon detected.\n");
			priv->hw_revision = CW1200_HW_REV_CUT20;
		}
		break;
	}
	case 4:
		pr_info("CW1x60 silicon detected.\n");
		priv->hw_revision = CW1X60_HW_REV;
		break;
	default:
		pr_err("Unsupported silicon major revision %d.\n",
		       major_revision);
		ret = -ENOTSUPP;
		goto out;
	}

	/* Checking for access mode */
	ret = config_reg_read(priv, &val32);
	if (ret < 0) {
		pr_err("Can't read config register.\n");
		goto out;
	}

	if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
		pr_err("Device is already in QUEUE mode!\n");
		ret = -EINVAL;
		goto out;
	}

	switch (priv->hw_type)  {
	case HIF_8601_SILICON:
		if (priv->hw_revision == CW1X60_HW_REV) {
			pr_err("Can't handle CW1160/1260 firmware load yet.\n");
			ret = -ENOTSUPP;
			goto out;
		}
		ret = cw1200_load_firmware_cw1200(priv);
		break;
	default:
		pr_err("Can't perform firmware load for hw type %d.\n",
		       priv->hw_type);
		ret = -ENOTSUPP;
		goto out;
	}
	if (ret < 0) {
		pr_err("Firmware load error.\n");
		goto out;
	}

	/* Enable interrupt signalling */
	priv->hwbus_ops->lock(priv->hwbus_priv);
	ret = __cw1200_irq_enable(priv, 1);
	priv->hwbus_ops->unlock(priv->hwbus_priv);
	if (ret < 0)
		goto unsubscribe;

	/* Configure device for MESSSAGE MODE */
	ret = config_reg_read(priv, &val32);
	if (ret < 0) {
		pr_err("Can't read config register.\n");
		goto unsubscribe;
	}
	ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
	if (ret < 0) {
		pr_err("Can't write config register.\n");
		goto unsubscribe;
	}

	/* Unless we read the CONFIG Register we are
	 * not able to get an interrupt
	 */
	mdelay(10);
	config_reg_read(priv, &val32);

out:
	return ret;

unsubscribe:
	/* Disable interrupt signalling */
	priv->hwbus_ops->lock(priv->hwbus_priv);
	ret = __cw1200_irq_enable(priv, 0);
	priv->hwbus_ops->unlock(priv->hwbus_priv);
	return ret;
}
