/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * MultiMediaCard (MMC), eMMC and Secure Digital (SD) write support code.
 * This code is controller independent.
 */

#include <stdlib.h>

#include "sd_mmc.h"
#include "storage.h"

static uint32_t storage_write(struct storage_media *media, uint32_t start,
	uint64_t block_count, const void *src)
{
	struct mmc_command cmd;
	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;

	cmd.resp_type = CARD_RSP_R1;
	cmd.flags = 0;

	if (block_count > 1)
		cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK;
	else
		cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK;

	if (media->high_capacity)
		cmd.cmdarg = start;
	else
		cmd.cmdarg = start * media->write_bl_len;

	struct mmc_data data;
	data.src = src;
	data.blocks = block_count;
	data.blocksize = media->write_bl_len;
	data.flags = DATA_FLAG_WRITE;

	if (ctrlr->send_cmd(ctrlr, &cmd, &data)) {
		sd_mmc_error("Write failed\n");
		return 0;
	}

	/* SPI multiblock writes terminate using a special
	 * token, not a STOP_TRANSMISSION request.
	 */
	if ((block_count > 1) && !(ctrlr->caps
		& DRVR_CAP_AUTO_CMD12)) {
		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
		cmd.cmdarg = 0;
		cmd.resp_type = CARD_RSP_R1b;
		cmd.flags = CMD_FLAG_IGNORE_INHIBIT;
		if (ctrlr->send_cmd(ctrlr, &cmd, NULL)) {
			sd_mmc_error("Failed to send stop cmd\n");
			return 0;
		}

		/* Waiting for the ready status */
		sd_mmc_send_status(media, SD_MMC_IO_RETRIES);
	}

	return block_count;
}

uint64_t storage_block_write(struct storage_media *media, uint64_t start,
	uint64_t count, const void *buffer)
{
	const uint8_t *src = (const uint8_t *)buffer;

	if (storage_block_setup(media, start, count, 0) == 0)
		return 0;

	uint64_t todo = count;
	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
	do {
		uint64_t cur = MIN(todo, ctrlr->b_max);
		if (storage_write(media, start, cur, src) != cur)
			return 0;
		todo -= cur;
		start += cur;
		src += cur * media->write_bl_len;
	} while (todo > 0);
	return count;
}

uint64_t storage_block_fill_write(struct storage_media *media, uint64_t start,
	uint64_t count, uint32_t fill_pattern)
{
	if (storage_block_setup(media, start, count, 0) == 0)
		return 0;

	struct sd_mmc_ctrlr *ctrlr = media->ctrlr;
	uint64_t block_size = media->write_bl_len;
	/*
	 * We allocate max 4 MiB buffer on heap and set it to fill_pattern and
	 * perform mmc_write operation using this 4MiB buffer until requested
	 * size on disk is written by the fill byte.
	 *
	 * 4MiB was chosen after repeating several experiments with the max
	 * buffer size to be used. Using 1 lba i.e. block_size buffer results in
	 * very large fill_write time. On the other hand, choosing 4MiB, 8MiB or
	 * even 128 Mib resulted in similar write times. With 2MiB, the
	 * fill_write time increased by several seconds. So, 4MiB was chosen as
	 * the default max buffer size.
	 */
	uint64_t heap_lba = (4 * MiB) / block_size;
	/*
	 * Actual allocated buffer size is minimum of three entities:
	 * 1) 4MiB equivalent in lba
	 * 2) count: Number of lbas to overwrite
	 * 3) ctrlr->b_max: Max lbas that the block device allows write
	 * operation on at a time.
	 */
	uint64_t buffer_lba = MIN(MIN(heap_lba, count), ctrlr->b_max);

	uint64_t buffer_bytes = buffer_lba * block_size;
	uint64_t buffer_words = buffer_bytes / sizeof(uint32_t);
	uint32_t *buffer = malloc(buffer_bytes);
	uint32_t *ptr = buffer;

	for (; buffer_words ; buffer_words--)
		*ptr++ = fill_pattern;

	uint64_t todo = count;
	int ret = 0;

	do {
		uint64_t curr_lba = MIN(buffer_lba, todo);

		if (storage_write(media, start, curr_lba, buffer) != curr_lba)
			goto cleanup;
		todo -= curr_lba;
		start += curr_lba;
	} while (todo > 0);

	ret = count;

cleanup:
	free(buffer);
	return ret;
}
