/*
 * Copyright (C) 2018 Synaptics Incorporated. All rights reserved.
 *
 * This program 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.
 *
 * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND
 * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY
 * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR
 * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND
 * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF
 * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT
 * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY
 * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS.
 */
#include "global.h"
#include "Galois_memmap.h"
#include "soc.h"
#include "diag_common.h"
#include "diag_misc.h"
#include "usb_memmap.h"
#include "usb_typedefs.h"
#include "hw.h"
#include "core.h"
#include "util.h"

unsigned int g_USB_M2M_src = USB_MASS_M2M_WRITE_BASE;
unsigned int g_USB_M2M_dst = USB_MASS_M2M_READ_BASE;
unsigned int g_USB_M2M_blkcnt = A_F_V( 128, 128, USB_MASS_M2M_BLK_COUNT);
unsigned int g_var_m2m_blk_count = A_F_V( 128, 128, USB_MASS_M2M_BLK_COUNT);
#define GET_VM_ADDR(addr)	((unsigned char*)(unsigned long long)(addr))

void memXOR(unsigned int a_u32target, unsigned int a_u32size,unsigned int a_u32iteration)
{
	unsigned int i;
	unsigned char* pTgt=GET_VM_ADDR(a_u32target);
	for (i=0;i<a_u32size;i++)
	{
		*pTgt=(a_u32iteration&0xff)^i;
		pTgt++;
	}
}

static unsigned int y = 1U;
unsigned int rand_r(unsigned int *seedp)
{
	*seedp ^= (*seedp << 13);
	*seedp ^= (*seedp >> 17);
	*seedp ^= (*seedp << 5);

	return *seedp;
}

unsigned int rand(void)
{
	return rand_r(&y);
}

int memCheck(unsigned int a_u32target, unsigned int a_u32source,unsigned int a_u32size,unsigned int a_u32iteration)
{
	unsigned int iRtn,iErrCnt,i;
	unsigned char iData,iTest;
	unsigned char* pTgt=GET_VM_ADDR(a_u32target);
	iRtn=iErrCnt=0;

	for (i=0;i<a_u32size;i++)
	{
		iData=*pTgt;
		iTest=((unsigned char)a_u32iteration&0xff)^i;
		if(iData!=iTest)
		{
			iRtn=1;		  // failed
			iErrCnt++;
			dbg_printf(PRN_ERR,"memCheck: Read 0x%02x(0x%02x), Expected 0x%02x @ 0x%08x(0x%08x)\n",
				iData,*pTgt,(a_u32iteration^i)&0xFF,(unsigned long long)pTgt,a_u32source+i);

		}

		if (iErrCnt>=1)
			break;
		pTgt++;
	}
	return iRtn;
}

int cmd_USB_RM2M()
{
	int ret = 0;
	int cnt = 1;   // iteration
	int start_blk = 8;   // start block number
	unsigned int src_addr;
	unsigned int dest_addr;
	unsigned int window;
	int i;
	int all_ret = 0;
	int blkcnt;

	cnt = 1;
	blkcnt = 1;
	src_addr = USB_MASS_M2M_WRITE_BASE;
	dest_addr = USB_MASS_M2M_READ_BASE;
	window = 0x8000;


	for(i=0;i<cnt;i++){
		g_USB_M2M_src = (src_addr + rand()%window) & 0xfffffffc;
		g_USB_M2M_dst = (dest_addr + rand()%window) & 0xfffffffc;
		g_USB_M2M_blkcnt = 1 + rand()%blkcnt;

		memset((void *)(unsigned long long)g_USB_M2M_dst, 0x00, g_mass_blen*g_USB_M2M_blkcnt);
		// pre-fill write pattern
		memXOR(g_USB_M2M_src, g_mass_blen * g_USB_M2M_blkcnt, i);

		usb_storage_write((unsigned char *)(unsigned long long)g_USB_M2M_src, start_blk, g_USB_M2M_blkcnt);
		usb_storage_read((unsigned char *)(unsigned long long)g_USB_M2M_dst, start_blk, g_USB_M2M_blkcnt);
		ret = memCheck(g_USB_M2M_dst, g_USB_M2M_src, g_mass_blen*g_USB_M2M_blkcnt, i);
		dbg_printf(PRN_RES,"USB RM2M test %s (src:0x%x dst:0x%x blkcnt:%d blk_len:%d)\n"
		, ret?"FAIL":"PASS"
		, g_USB_M2M_src
		, g_USB_M2M_dst
		, g_USB_M2M_blkcnt
		, g_mass_blen);

		all_ret |= ret;
		if (ret)
			break;
	}
	dbg_printf(PRN_RES,"Overall USB RM2M test %s\n",all_ret ? "FAIL":"PASS");

	return all_ret;
}

void usb_reset()
{
	unsigned int data;

	// 1.)	After power on reset, keep "usbOtgForceStckyRst" register (BF_PERIF_uUSB_CTRL_FORCE_PHYSTCKYRST) value to 0.
	BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_PERIF + RA_PERIF_USB_CTRL, &data);
	data &= ~MSK32PERIF_USB_CTRL_FORCE_PHYSTCKYRST;
	BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_PERIF + RA_PERIF_USB_CTRL, data);

	delay_1us(10);

	BFM_HOST_Bus_Read32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN), &data);

	data &= ~(MSK32Gbl_perifStickyResetN_usbOtgHresetn |
			  MSK32Gbl_perifStickyResetN_usbOtgPrstn );
	data |= MSK32Gbl_perifStickyResetN_usbOtgPhyreset;
	BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE+RA_Gbl_perifStickyResetN, data); // Assert USB MAC + PHY

	delay_1us(1000);

	// 2.)	Check "BF_usbPHY_uUSB_RB_CLK_RDY" status.
	if (usb_phy_init()) {
		return ;
	}

	//Set BF_PERIF_uUSB_CTRL_FORCE_PHYSTCKYRST to 1 after the read back value of “BF_usbPHY_uUSB_RB_CLK_RDY” is 1.
	BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_PERIF + RA_PERIF_USB_CTRL, &data);
	data |= MSK32PERIF_USB_CTRL_FORCE_PHYSTCKYRST;
	BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_PERIF + RA_PERIF_USB_CTRL, data);

	delay_1us(10);

	// 5. Deassert USB MAC PRSTN, phy digital
	BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN, &data);
	data |= MSK32Gbl_perifStickyResetN_usbOtgPrstn;
	BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN, data);

	// 6. wait for 10us.
	delay_1us(10);

	// 7. Deassert USB MAC HRESETN - ahb
	BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN, &data);
	data |= MSK32Gbl_perifStickyResetN_usbOtgHresetn;
	BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN, data);

	dbg_printf(PRN_RES, " USB2 controller is out of reset, phy is ready\n");
}


