/*
 * tiomap_io.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Implementation for the io read/write routines.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/platform_data/dsp-omap.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Platform Manager */
#include <dspbridge/dev.h>
#include <dspbridge/drv.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/wdt.h>

/*  ----------------------------------- specific to this file */
#include "_tiomap.h"
#include "_tiomap_pwr.h"
#include "tiomap_io.h"

static u32 ul_ext_base;
static u32 ul_ext_end;

static u32 shm0_end;
static u32 ul_dyn_ext_base;
static u32 ul_trace_sec_beg;
static u32 ul_trace_sec_end;
static u32 ul_shm_base_virt;

bool symbols_reloaded = true;

/*
 *  ======== read_ext_dsp_data ========
 *      Copies DSP external memory buffers to the host side buffers.
 */
int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
			     u8 *host_buff, u32 dsp_addr,
			     u32 ul_num_bytes, u32 mem_type)
{
	int status = 0;
	struct bridge_dev_context *dev_context = dev_ctxt;
	u32 offset;
	u32 ul_tlb_base_virt = 0;
	u32 ul_shm_offset_virt = 0;
	u32 dw_ext_prog_virt_mem;
	u32 dw_base_addr = dev_context->dsp_ext_base_addr;
	bool trace_read = false;

	if (!ul_shm_base_virt) {
		status = dev_get_symbol(dev_context->dev_obj,
					SHMBASENAME, &ul_shm_base_virt);
	}

	/* Check if it is a read of Trace section */
	if (!status && !ul_trace_sec_beg) {
		status = dev_get_symbol(dev_context->dev_obj,
					DSP_TRACESEC_BEG, &ul_trace_sec_beg);
	}

	if (!status && !ul_trace_sec_end) {
		status = dev_get_symbol(dev_context->dev_obj,
					DSP_TRACESEC_END, &ul_trace_sec_end);
	}

	if (!status) {
		if ((dsp_addr <= ul_trace_sec_end) &&
		    (dsp_addr >= ul_trace_sec_beg))
			trace_read = true;
	}

	/* If reading from TRACE, force remap/unmap */
	if (trace_read && dw_base_addr) {
		dw_base_addr = 0;
		dev_context->dsp_ext_base_addr = 0;
	}

	if (!dw_base_addr) {
		/* Initialize ul_ext_base and ul_ext_end */
		ul_ext_base = 0;
		ul_ext_end = 0;

		/* Get DYNEXT_BEG, EXT_BEG and EXT_END. */
		if (!status && !ul_dyn_ext_base) {
			status = dev_get_symbol(dev_context->dev_obj,
						DYNEXTBASE, &ul_dyn_ext_base);
		}

		if (!status) {
			status = dev_get_symbol(dev_context->dev_obj,
						EXTBASE, &ul_ext_base);
		}

		if (!status) {
			status = dev_get_symbol(dev_context->dev_obj,
						EXTEND, &ul_ext_end);
		}

		/* Trace buffer is right after the shm SEG0,
		 *  so set the base address to SHMBASE */
		if (trace_read) {
			ul_ext_base = ul_shm_base_virt;
			ul_ext_end = ul_trace_sec_end;
		}


		if (ul_ext_end < ul_ext_base)
			status = -EPERM;

		if (!status) {
			ul_tlb_base_virt =
			    dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
			dw_ext_prog_virt_mem =
			    dev_context->atlb_entry[0].gpp_va;

			if (!trace_read) {
				ul_shm_offset_virt =
				    ul_shm_base_virt - ul_tlb_base_virt;
				ul_shm_offset_virt +=
				    PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base +
						  1, HW_PAGE_SIZE64KB);
				dw_ext_prog_virt_mem -= ul_shm_offset_virt;
				dw_ext_prog_virt_mem +=
				    (ul_ext_base - ul_dyn_ext_base);
				dev_context->dsp_ext_base_addr =
				    dw_ext_prog_virt_mem;

				/*
				 * This dsp_ext_base_addr will get cleared
				 * only when the board is stopped.
				*/
				if (!dev_context->dsp_ext_base_addr)
					status = -EPERM;
			}

			dw_base_addr = dw_ext_prog_virt_mem;
		}
	}

	if (!dw_base_addr || !ul_ext_base || !ul_ext_end)
		status = -EPERM;

	offset = dsp_addr - ul_ext_base;

	if (!status)
		memcpy(host_buff, (u8 *) dw_base_addr + offset, ul_num_bytes);

	return status;
}

/*
 *  ======== write_dsp_data ========
 *  purpose:
 *      Copies buffers to the DSP internal/external memory.
 */
int write_dsp_data(struct bridge_dev_context *dev_context,
			  u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes,
			  u32 mem_type)
{
	u32 offset;
	u32 dw_base_addr = dev_context->dsp_base_addr;
	struct cfg_hostres *resources = dev_context->resources;
	int status = 0;
	u32 base1, base2, base3;
	base1 = OMAP_DSP_MEM1_SIZE;
	base2 = OMAP_DSP_MEM2_BASE - OMAP_DSP_MEM1_BASE;
	base3 = OMAP_DSP_MEM3_BASE - OMAP_DSP_MEM1_BASE;

	if (!resources)
		return -EPERM;

	offset = dsp_addr - dev_context->dsp_start_add;
	if (offset < base1) {
		dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[2],
						  resources->mem_length[2]);
	} else if (offset > base1 && offset < base2 + OMAP_DSP_MEM2_SIZE) {
		dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[3],
						  resources->mem_length[3]);
		offset = offset - base2;
	} else if (offset >= base2 + OMAP_DSP_MEM2_SIZE &&
		   offset < base3 + OMAP_DSP_MEM3_SIZE) {
		dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[4],
						  resources->mem_length[4]);
		offset = offset - base3;
	} else {
		return -EPERM;
	}
	if (ul_num_bytes)
		memcpy((u8 *) (dw_base_addr + offset), host_buff, ul_num_bytes);
	else
		*((u32 *) host_buff) = dw_base_addr + offset;

	return status;
}

/*
 *  ======== write_ext_dsp_data ========
 *  purpose:
 *      Copies buffers to the external memory.
 *
 */
int write_ext_dsp_data(struct bridge_dev_context *dev_context,
			      u8 *host_buff, u32 dsp_addr,
			      u32 ul_num_bytes, u32 mem_type,
			      bool dynamic_load)
{
	u32 dw_base_addr = dev_context->dsp_ext_base_addr;
	u32 dw_offset = 0;
	u8 temp_byte1, temp_byte2;
	u8 remain_byte[4];
	s32 i;
	int ret = 0;
	u32 dw_ext_prog_virt_mem;
	u32 ul_tlb_base_virt = 0;
	u32 ul_shm_offset_virt = 0;
	struct cfg_hostres *host_res = dev_context->resources;
	bool trace_load = false;
	temp_byte1 = 0x0;
	temp_byte2 = 0x0;

	if (symbols_reloaded) {
		/* Check if it is a load to Trace section */
		ret = dev_get_symbol(dev_context->dev_obj,
				     DSP_TRACESEC_BEG, &ul_trace_sec_beg);
		if (!ret)
			ret = dev_get_symbol(dev_context->dev_obj,
					     DSP_TRACESEC_END,
					     &ul_trace_sec_end);
	}
	if (!ret) {
		if ((dsp_addr <= ul_trace_sec_end) &&
		    (dsp_addr >= ul_trace_sec_beg))
			trace_load = true;
	}

	/* If dynamic, force remap/unmap */
	if ((dynamic_load || trace_load) && dw_base_addr) {
		dw_base_addr = 0;
		MEM_UNMAP_LINEAR_ADDRESS((void *)
					 dev_context->dsp_ext_base_addr);
		dev_context->dsp_ext_base_addr = 0x0;
	}
	if (!dw_base_addr) {
		if (symbols_reloaded)
			/* Get SHM_BEG  EXT_BEG and EXT_END. */
			ret = dev_get_symbol(dev_context->dev_obj,
					     SHMBASENAME, &ul_shm_base_virt);
		if (dynamic_load) {
			if (!ret) {
				if (symbols_reloaded)
					ret =
					    dev_get_symbol
					    (dev_context->dev_obj, DYNEXTBASE,
					     &ul_ext_base);
			}
			if (!ret) {
				/* DR  OMAPS00013235 : DLModules array may be
				 * in EXTMEM. It is expected that DYNEXTMEM and
				 * EXTMEM are contiguous, so checking for the
				 * upper bound at EXTEND should be Ok. */
				if (symbols_reloaded)
					ret =
					    dev_get_symbol
					    (dev_context->dev_obj, EXTEND,
					     &ul_ext_end);
			}
		} else {
			if (symbols_reloaded) {
				if (!ret)
					ret =
					    dev_get_symbol
					    (dev_context->dev_obj, EXTBASE,
					     &ul_ext_base);
				if (!ret)
					ret =
					    dev_get_symbol
					    (dev_context->dev_obj, EXTEND,
					     &ul_ext_end);
			}
		}
		/* Trace buffer it right after the shm SEG0, so set the
		 *      base address to SHMBASE */
		if (trace_load)
			ul_ext_base = ul_shm_base_virt;

		if (ul_ext_end < ul_ext_base)
			ret = -EPERM;

		if (!ret) {
			ul_tlb_base_virt =
			    dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;

			if (symbols_reloaded) {
				ret = dev_get_symbol
					    (dev_context->dev_obj,
					     DSP_TRACESEC_END, &shm0_end);
				if (!ret) {
					ret =
					    dev_get_symbol
					    (dev_context->dev_obj, DYNEXTBASE,
					     &ul_dyn_ext_base);
				}
			}
			ul_shm_offset_virt =
			    ul_shm_base_virt - ul_tlb_base_virt;
			if (trace_load) {
				dw_ext_prog_virt_mem =
				    dev_context->atlb_entry[0].gpp_va;
			} else {
				dw_ext_prog_virt_mem = host_res->mem_base[1];
				dw_ext_prog_virt_mem +=
				    (ul_ext_base - ul_dyn_ext_base);
			}

			dev_context->dsp_ext_base_addr =
			    (u32) MEM_LINEAR_ADDRESS((void *)
						     dw_ext_prog_virt_mem,
						     ul_ext_end - ul_ext_base);
			dw_base_addr += dev_context->dsp_ext_base_addr;
			/* This dsp_ext_base_addr will get cleared only when
			 * the board is stopped. */
			if (!dev_context->dsp_ext_base_addr)
				ret = -EPERM;
		}
	}
	if (!dw_base_addr || !ul_ext_base || !ul_ext_end)
		ret = -EPERM;

	if (!ret) {
		for (i = 0; i < 4; i++)
			remain_byte[i] = 0x0;

		dw_offset = dsp_addr - ul_ext_base;
		/* Also make sure the dsp_addr is < ul_ext_end */
		if (dsp_addr > ul_ext_end || dw_offset > dsp_addr)
			ret = -EPERM;
	}
	if (!ret) {
		if (ul_num_bytes)
			memcpy((u8 *) dw_base_addr + dw_offset, host_buff,
			       ul_num_bytes);
		else
			*((u32 *) host_buff) = dw_base_addr + dw_offset;
	}
	/* Unmap here to force remap for other Ext loads */
	if ((dynamic_load || trace_load) && dev_context->dsp_ext_base_addr) {
		MEM_UNMAP_LINEAR_ADDRESS((void *)
					 dev_context->dsp_ext_base_addr);
		dev_context->dsp_ext_base_addr = 0x0;
	}
	symbols_reloaded = false;
	return ret;
}

int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val)
{
#ifdef CONFIG_TIDSPBRIDGE_DVFS
	u32 opplevel = 0;
#endif
	struct omap_dsp_platform_data *pdata =
		omap_dspbridge_dev->dev.platform_data;
	struct cfg_hostres *resources = dev_context->resources;
	int status = 0;
	u32 temp;

	if (!dev_context->mbox)
		return 0;

	if (!resources)
		return -EPERM;

	if (dev_context->brd_state == BRD_DSP_HIBERNATION ||
	    dev_context->brd_state == BRD_HIBERNATION) {
#ifdef CONFIG_TIDSPBRIDGE_DVFS
		if (pdata->dsp_get_opp)
			opplevel = (*pdata->dsp_get_opp) ();
		if (opplevel == VDD1_OPP1) {
			if (pdata->dsp_set_min_opp)
				(*pdata->dsp_set_min_opp) (VDD1_OPP2);
		}
#endif
		/* Restart the peripheral clocks */
		dsp_clock_enable_all(dev_context->dsp_per_clks);
		dsp_wdt_enable(true);

		/*
		 * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
		 *     in CM_AUTOIDLE_PLL_IVA2 register
		 */
		(*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
				OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL);

		/*
		 * 7:4 IVA2_DPLL_FREQSEL - IVA2 internal frq set to
		 *     0.75 MHz - 1.0 MHz
		 * 2:0 EN_IVA2_DPLL - Enable IVA2 DPLL in lock mode
		 */
		(*pdata->dsp_cm_rmw_bits)(OMAP3430_IVA2_DPLL_FREQSEL_MASK |
				OMAP3430_EN_IVA2_DPLL_MASK,
				0x3 << OMAP3430_IVA2_DPLL_FREQSEL_SHIFT |
				0x7 << OMAP3430_EN_IVA2_DPLL_SHIFT,
				OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);

		/* Restore mailbox settings */
		omap_mbox_restore_ctx(dev_context->mbox);

		/* Access MMU SYS CONFIG register to generate a short wakeup */
		temp = readl(resources->dmmu_base + 0x10);

		dev_context->brd_state = BRD_RUNNING;
	} else if (dev_context->brd_state == BRD_RETENTION) {
		/* Restart the peripheral clocks */
		dsp_clock_enable_all(dev_context->dsp_per_clks);
	}

	status = omap_mbox_msg_send(dev_context->mbox, mb_val);

	if (status) {
		pr_err("omap_mbox_msg_send Fail and status = %d\n", status);
		status = -EPERM;
	}

	return 0;
}
