/*
 * Copyright (C) 2016 Marvell International Ltd.
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 * https://spdx.org/licenses
 */
#include <debug.h>
#include <io_addr_dec.h>
#include <mmio.h>
#include <plat_marvell.h>

#define MVEBU_DEC_WIN_CTRL_REG(base, win, off)	(MVEBU_REGS_BASE + (base) + \
						(win) * (off))
#define MVEBU_DEC_WIN_BASE_REG(base, win, off)	(MVEBU_REGS_BASE + (base) + \
						(win) * (off) + 0x4)
#define MVEBU_DEC_WIN_REMAP_REG(base, win, off)	(MVEBU_REGS_BASE + (base) + \
						(win) * (off) + 0x8)

#define MVEBU_DEC_WIN_CTRL_SIZE_OFF		(16)
#define MVEBU_DEC_WIN_ENABLE			(0x1)
#define MVEBU_DEC_WIN_CTRL_ATTR_OFF		(8)
#define MVEBU_DEC_WIN_CTRL_TARGET_OFF		(4)
#define MVEBU_DEC_WIN_CTRL_EN_OFF		(0)
#define MVEBU_DEC_WIN_BASE_OFF			(16)

#define MVEBU_WIN_BASE_SIZE_ALIGNMENT		(0x10000)

/* There are up to 14 IO unit which need address decode in Armada-3700 */
#define IO_UNIT_NUM_MAX				(14)

#define MVEBU_MAX_ADDRSS_4GB			(0x100000000ULL)


static void set_io_addr_dec_win(int win_id, uintptr_t base_addr,
				uintptr_t win_size,
				struct dec_win_config *dec_win)
{
	uint32_t ctrl = 0;
	uint32_t base = 0;

	/* set size */
	ctrl = ((win_size / MVEBU_WIN_BASE_SIZE_ALIGNMENT) - 1) <<
	       MVEBU_DEC_WIN_CTRL_SIZE_OFF;
	/* set attr according to IO decode window */
	ctrl |= dec_win->win_attr << MVEBU_DEC_WIN_CTRL_ATTR_OFF;
	/* set target */
	ctrl |= DRAM_CPU_DEC_TARGET_NUM << MVEBU_DEC_WIN_CTRL_TARGET_OFF;
	/* set base */
	base = (base_addr / MVEBU_WIN_BASE_SIZE_ALIGNMENT) <<
	       MVEBU_DEC_WIN_BASE_OFF;

	/* set base address*/
	mmio_write_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base,
		      win_id, dec_win->win_offset),
		      base);
	/* set remap window, some unit does not have remap window */
	if (win_id < dec_win->max_remap)
		mmio_write_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base,
			      win_id, dec_win->win_offset), base);
	/* set control register */
	mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base,
		      win_id, dec_win->win_offset), ctrl);
	/* enable the address decode window at last to make it effective */
	ctrl |= MVEBU_DEC_WIN_ENABLE << MVEBU_DEC_WIN_CTRL_EN_OFF;
	mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base,
		      win_id, dec_win->win_offset), ctrl);

	INFO("set_io_addr_dec %d result: ctrl(0x%x) base(0x%x)",
	     win_id, mmio_read_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base,
	     win_id, dec_win->win_offset)),
	     mmio_read_32(MVEBU_DEC_WIN_BASE_REG(dec_win->dec_reg_base,
			  win_id, dec_win->win_offset)));
	if (win_id < dec_win->max_remap)
		INFO(" remap(%x)\n",
		     mmio_read_32(MVEBU_DEC_WIN_REMAP_REG(dec_win->dec_reg_base,
		     win_id, dec_win->win_offset)));
	else
		INFO("\n");
}

/* Set io decode window */
static int set_io_addr_dec(struct dram_win_map *win_map,
			   struct dec_win_config *dec_win)
{
	struct dram_win *win;
	int id;

	/* disable all windows first */
	for (id = 0; id < dec_win->max_dram_win; id++)
		mmio_write_32(MVEBU_DEC_WIN_CTRL_REG(dec_win->dec_reg_base, id,
			      dec_win->win_offset), 0);

	/* configure IO decode windows for DRAM, inheritate DRAM size,
	 * base and target from CPU-DRAM decode window and others
	 * from hard coded IO decode window settings array.
	 */
	if (win_map->dram_win_num > dec_win->max_dram_win) {
		/*
		 * If cpu dram windows number exceeds the io decode windows
		 * max number, then fill the first io decode window
		 * with base(0) and size(4GB).
		 */
		set_io_addr_dec_win(0, 0, MVEBU_MAX_ADDRSS_4GB, dec_win);

		return 0;
	}

	for (id = 0; id < win_map->dram_win_num; id++, win++) {
		win = &win_map->dram_windows[id];
		set_io_addr_dec_win(id, win->base_addr, win->win_size, dec_win);
	}

	return 0;
}

/*
 * init_io_addr_dec
 *
 * This function initializes io address decoder windows by
 * cpu dram window mapping information
 *
 * @input: N/A
 *     - dram_wins_map: cpu dram windows mapping
 *     - io_dec_config: io address decoder windows configuration
 *     - io_unit_num: io address decoder unit number
 * @output: N/A
 *
 * @return:  0 on success and others on failure
 */
int init_io_addr_dec(struct dram_win_map *dram_wins_map,
		     struct dec_win_config *io_dec_config, uint32_t io_unit_num)
{
	int32_t index;
	struct dec_win_config *io_dec_win;
	int32_t ret;

	INFO("Initializing IO address decode windows\n");

	if (io_dec_config == NULL || io_unit_num == 0) {
		ERROR("No IO address decoder windows configurations!\n");
		return -1;
	}

	if (io_unit_num > IO_UNIT_NUM_MAX) {
		ERROR("IO address decoder windows number %d is over max %d\n",
		      io_unit_num, IO_UNIT_NUM_MAX);
		return -1;
	}

	if (dram_wins_map == NULL) {
		ERROR("No cpu dram decoder windows map!\n");
		return -1;
	}

	for (index = 0; index < dram_wins_map->dram_win_num; index++)
		INFO("DRAM mapping %d base(0x%lx) size(0x%lx)\n",
		     index, dram_wins_map->dram_windows[index].base_addr,
		     dram_wins_map->dram_windows[index].win_size);

	/* Set address decode window for each IO */
	for (index = 0; index < io_unit_num; index++) {
		io_dec_win = io_dec_config + index;
		ret = set_io_addr_dec(dram_wins_map, io_dec_win);
		if (ret) {
			ERROR("Failed to set IO address decode\n");
			return -1;
		}
		INFO("Set IO decode window successfully, base(0x%x)",
		     io_dec_win->dec_reg_base);
		INFO(" win_attr(%x) max_dram_win(%d) max_remap(%d)",
		     io_dec_win->win_attr, io_dec_win->max_dram_win,
		     io_dec_win->max_remap);
		INFO(" win_offset(%d)\n", io_dec_win->win_offset);
	}

	return 0;
}
