/*
 * 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 "Galois_memmap.h"
#include "usbPHY.h"
#include "global.h"
#include "diag_common.h"
#include "diag_misc.h"
#include "core.h"
#include "util.h"

unsigned long g_usb_phy_ctrl0 = 0x0EB35E84;
unsigned long g_usb_phy_ctrl1 = 0x80F99004;

#define PHY_PARSE(str,len,offset){ dbg_printf(PRN_RES,"\t%16s: %db'0x%x\n",str,len,(data>>offset)&((len<<1)-1));}

int usb_phy_init(void)
{
	unsigned int reg;
    unsigned int timeout = 1000000;

    // 1. Program USB_CTRL0
    BFM_HOST_Bus_Write32(MEMMAP_USB0_REG_BASE + 0x8000 + RA_usbPHY_USB_CTRL0, g_usb_phy_ctrl0);

    // 2. Program USB_CTRL1
    BFM_HOST_Bus_Write32(MEMMAP_USB0_REG_BASE + 0x8000 + RA_usbPHY_USB_CTRL1, g_usb_phy_ctrl1);

    // 3. Deassert USB PHY Reset
    BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN, &reg);
    reg &= ~MSK32Gbl_perifStickyResetN_usbOtgPhyreset;
    BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN, reg);

    // 4. Wait for 2ms
    mydelay_us(2000);

    while (timeout) {

        BFM_HOST_Bus_Read32(MEMMAP_USB0_REG_BASE + 0x8000 +RA_usbPHY_USB_RB, &reg);
        if (reg & MSK32usbPHY_USB_RB_CLK_RDY) // UTMI clock
            break;
        delay_1us(1);
        timeout--;
    }

    if (timeout == 0) {
        dbg_printf(PRN_RES, "USB PHY internal PLL is not ready\n");
        return -1;
    } else {
        return 0;
    }

}

static const char * phy_reg_name[]=
{
    "USB_CTRL0",
    "USB_CTRL1",
    "USB_CTRL11",
    "USB_PHY_RB",
    "USB_RB",
    "OTG_CORE_CTRL"
};

int usb2_phy_status(int long_dump)
{
	int i;
	unsigned long addr,data;

	for (i=0 ; i<6; i++){
		addr = MEMMAP_USB0_REG_BASE + 0x8000 + i*4;
		BFM_HOST_Bus_Read32(addr,&data);
		dbg_printf(PRN_RES,"[0x%08lx] %12s : 0x%08lx\n",addr, phy_reg_name[i], data);
		if (long_dump){
			switch (i){
            case 0:
				PHY_PARSE("HSDRV0", 1, 0);
				PHY_PARSE("HSDRV1", 1, 1);
				PHY_PARSE("CLKSEL", 1, 2);
				PHY_PARSE("HS_CHIRP_EN", 1, 3);
				PHY_PARSE("RES_CTL_REG", 4, 4);
				PHY_PARSE("PLL_FB_DIV_CTL", 7, 8);
				PHY_PARSE("PLL_LOCK_BYPASS",1,15);
				PHY_PARSE("PLL_PRE_DIV_CTL",3,16);
				PHY_PARSE("PLL_PRE_MINUS0P5",1,19);
				PHY_PARSE("TERM_CAL_EN",1,20);
				PHY_PARSE("BGR_EN",1,21);
				PHY_PARSE("RES_DIV_EN",1,22);
				PHY_PARSE("RES_SEL",1,23);
				PHY_PARSE("CP_INT_CTRL",2,24);
				PHY_PARSE("DRV_SWING_CTL",2,26);
				PHY_PARSE("GM_CTRL",2,28);
				PHY_PARSE("KVCCO_CTRL",2,30);
				break;
            case 1:
				PHY_PARSE("TEST",24,0);
				PHY_PARSE("TEST_MODE",5,24);
				PHY_PARSE("CP_PROP_CTL",3,29);
				break;
            case 2:
				PHY_PARSE("DP_PULLDOWN",1,0);
				PHY_PARSE("DM_PULLDOWN",1,1);
				PHY_PARSE("OP_MODE",2,2);
				PHY_PARSE("TXBITSTUFFEN",1,4);
				PHY_PARSE("TXBITSTUFFENH",1,5);
				PHY_PARSE("DIG_DBG_SEL",5,6);
				break;
            case 3:
				PHY_PARSE("LBK_ERR",1,0);
				break;
            case 4:
				PHY_PARSE("CLK_RDY",1,0);
				PHY_PARSE("RES_CAL_CODE",4,1);
				PHY_PARSE("RCV_SQ_REG",1,5);
				PHY_PARSE("SENRCV_REG",1,6);
				PHY_PARSE("SEPRCV_REG",1,7);
				PHY_PARSE("CLK_READY_REG",1,8);
				PHY_PARSE("LFSRCV_REG",1,9);
				PHY_PARSE("RCV_DED_REG",1,10);
				PHY_PARSE("ID_A_B_REG",1,11);
				PHY_PARSE("VBUS_VLD_REG",1,12);
				PHY_PARSE("VSESS_VLD_REG",1,13);
				PHY_PARSE("ADPPRB_REG",1,14);
				PHY_PARSE("ADPSNS_REG",1,15);
				break;
            case 5:
				PHY_PARSE("s_bigendian",1,0);
				PHY_PARSE("m_bigendian",1,1);
				PHY_PARSE("ss_scale_down",2,2);
				break;
			}
		}
	}
	return 0;
}

