/*
* Host Controller Driver for the Vixs Systems Xcode3 SDUH USB Host
*
* Copyright(C) 2007 Vixs Systems Limited
* http://www.Vixs.com
*
* Author and Maintainer - Jerry Wang
* jlwang@vixs.com
*
* This program is free software;you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*
*
*/
#ifdef CONFIG_USB_XCODE_HCD

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/pci_ids.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/byteorder.h>
#include "eagle.h"
#include "sduh-hcd.h"


u32 SDUH_HCD_REG_BASE = 0;
EXPORT_SYMBOL(SDUH_HCD_REG_BASE);

u32 SDUH_HCD_REF_CNT = 0;
EXPORT_SYMBOL(SDUH_HCD_REF_CNT);

u32 SDUH_HCD_ACTIVE_CNT = 0;
EXPORT_SYMBOL(SDUH_HCD_ACTIVE_CNT);

spinlock_t sduh_usb_indirect_reg_lock;
EXPORT_SYMBOL(sduh_usb_indirect_reg_lock);

XC_USBH_priv_struct g_XC_USBH_info;
EXPORT_SYMBOL(g_XC_USBH_info);

u32 g_XC_USBH_Global_Struct_Initialized = 0;
EXPORT_SYMBOL(g_XC_USBH_Global_Struct_Initialized);


#define SDUH_reg_readl(reg)			readl((u32 *)(SDUH_reg_base + reg))
#define SDUH_reg_writel(data, reg)	writel(data, (u32 *)(SDUH_reg_base + reg))

//TODO: [JLWANG] Add debug message if failed in case
u32 SDUH_writel(u32 SDUH_reg_base, u32 ehci_reg_addr, u32 value, SDUH_HC_reg_type type)
{
    u32 regVal = 0;
    unsigned long flags;
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    while(((regVal = SDUH_reg_readl(SDUH_IAS_REG))&0x1)== 1){};


    SDUH_reg_writel(value, SDUH_WDATA_REG);
    switch(type)
    {
        case EHCI_REG:
            SDUH_reg_writel(ehci_reg_addr|0x80000000, SDUH_EOC_REG);
            break;
        case OHCI_REG:
            SDUH_reg_writel(ehci_reg_addr|0x80000000, SDUH_OOC_REG);
            break;
        default:
            spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
            return 0;
            break;
    }
    while(((regVal = SDUH_reg_readl(SDUH_IAS_REG))&0x1)== 1){};
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);

    if(regVal&0x2) { printk("<1>" "Write USBH register fail\n"); return 0;};

    return 0;
};
EXPORT_SYMBOL(SDUH_writel);


u32 SDUH_readl(u32 SDUH_reg_base, u32 ehci_reg_addr, SDUH_HC_reg_type type)
{
    u32 regVal = 0;
    unsigned long  flags;
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    while(((regVal = SDUH_reg_readl(SDUH_IAS_REG))&0x1)== 1)
    {
//    			printk("<1>"" regVal value is %x\n", regVal);
    };


    switch(type)
    {
    case EHCI_REG:
    	SDUH_reg_writel(ehci_reg_addr, SDUH_EOC_REG);
    	break;
    case OHCI_REG:
    	SDUH_reg_writel(ehci_reg_addr, SDUH_OOC_REG);
                    break;
    default:
        spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    	 return 0;
    	 break;
    }
    while(((regVal = SDUH_reg_readl(SDUH_IAS_REG))&0x1)== 1)
    {
//    			printk("<1>"" regVal value is %x\n", regVal);
    };

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    if(regVal&0x2) { printk("<1>" "Read USBH register fail\n"); return 0;};

    regVal = SDUH_reg_readl(SDUH_RDATA_REG);

//    		printk("<1>"" regVal value is %x\n", regVal);
    return regVal;
};
EXPORT_SYMBOL(SDUH_readl);



u32 SDUH_data_buf_allocate(void)
{
    u32 ret;
    unsigned long  flags;
    
    if(g_XC_USBH_info.data_buf_pool.next == NULL)
    {
        printk("Failed to allocate data buffer\n");
        while(1);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    ret = g_XC_USBH_info.data_buf_pool.next->data_buf_paddr;

    g_XC_USBH_info.data_buf_pool.next = g_XC_USBH_info.data_buf_pool.next->next;

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    
    return ret;
}
EXPORT_SYMBOL(SDUH_data_buf_allocate);


void SDUH_data_buf_free(u32 paddr)
{
    u32 index;
   unsigned long  flags;
 
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    index = (paddr - g_XC_USBH_info.data_buf[0].data_buf_paddr)/USBH_DATA_BUF_SEG_SIZE;

    g_XC_USBH_info.data_buf[index].next = g_XC_USBH_info.data_buf_pool.next;
    g_XC_USBH_info.data_buf_pool.next = &g_XC_USBH_info.data_buf[index];
        
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
}

EXPORT_SYMBOL(SDUH_data_buf_free);


u32 SDUH_ed_hw_seg_allocate(dma_addr_t* handle)
{
    u32 ret;
    u32 flags;
    
    if(g_XC_USBH_info.ed_pool.next == NULL)
    {
        printk("Failed to allocate ed\n");
        while(1);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    *handle = (dma_addr_t)g_XC_USBH_info.ed_pool.next->ohci_ed_hw_seg_paddr;

    ret = (u32) g_XC_USBH_info.ed_pool.next->ohci_ed_hw_seg_vaddr;
    g_XC_USBH_info.ed_pool.next = g_XC_USBH_info.ed_pool.next->next;

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    
    return ret;
}
EXPORT_SYMBOL(SDUH_ed_hw_seg_allocate);



void SDUH_ed_hw_seg_free(u32 ed_hw_seg_vaddr)
{
    u32 index;
   u32 flags;
 
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    index = (ed_hw_seg_vaddr - g_XC_USBH_info.ed_hw_seg[0].ohci_ed_hw_seg_vaddr)/OHCI_ED_TD_SEG_DEFAULT_LEN;

    g_XC_USBH_info.ed_hw_seg[index].next = g_XC_USBH_info.ed_pool.next;
    g_XC_USBH_info.ed_pool.next = &g_XC_USBH_info.ed_hw_seg[index];
        
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
}

EXPORT_SYMBOL(SDUH_ed_hw_seg_free);

u32 SDUH_td_hw_seg_allocate(dma_addr_t* handle)
{
    u32 ret;
   u32 flags;
 
    
    if(g_XC_USBH_info.td_pool.next == NULL)
    {
        printk("Failed to allocate td\n");
        while(1);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    *handle = (dma_addr_t)g_XC_USBH_info.td_pool.next->ohci_td_hw_seg_paddr;

    ret = (u32) g_XC_USBH_info.td_pool.next->ohci_td_hw_seg_vaddr;
    g_XC_USBH_info.td_pool.next = g_XC_USBH_info.td_pool.next->next;
    
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    return ret;
}
EXPORT_SYMBOL(SDUH_td_hw_seg_allocate);

void SDUH_td_hw_seg_free(u32 td_hw_seg_vaddr)
{
    u32 index;
   u32 flags;
 
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    index = (td_hw_seg_vaddr - g_XC_USBH_info.td_hw_seg[0].ohci_td_hw_seg_vaddr)/OHCI_ED_TD_SEG_DEFAULT_LEN;

    g_XC_USBH_info.td_hw_seg[index].next = g_XC_USBH_info.td_pool.next;
    g_XC_USBH_info.td_pool.next = &g_XC_USBH_info.td_hw_seg[index];
        
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
}
EXPORT_SYMBOL(SDUH_td_hw_seg_free);


u32 SDUH_qtd_hw_seg_allocate(dma_addr_t* handle)
{
    u32 ret;
    u32 flags;
    
    if(g_XC_USBH_info.qtd_pool.next == NULL)
    {
        printk("Failed to allocate qtd\n");
        while(1);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    *handle = (dma_addr_t)g_XC_USBH_info.qtd_pool.next->ehci_qtd_hw_seg_paddr;

    ret = (u32) g_XC_USBH_info.qtd_pool.next->ehci_qtd_hw_seg_vaddr;
    g_XC_USBH_info.qtd_pool.next = g_XC_USBH_info.qtd_pool.next->next;

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    
    return ret;
}

EXPORT_SYMBOL(SDUH_qtd_hw_seg_allocate);


void SDUH_qtd_hw_seg_free(u32 qtd_hw_seg_vaddr)
{
    u32 index;
   u32 flags;
 
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    index = (qtd_hw_seg_vaddr - g_XC_USBH_info.qtd_hw_seg[0].ehci_qtd_hw_seg_vaddr)/EHCI_QH_QTD_SEG_DEFAULT_LEN;

    g_XC_USBH_info.qtd_hw_seg[index].next = g_XC_USBH_info.qtd_pool.next;
    g_XC_USBH_info.qtd_pool.next = &g_XC_USBH_info.qtd_hw_seg[index];
        
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
}

EXPORT_SYMBOL(SDUH_qtd_hw_seg_free);

u32 SDUH_qh_hw_seg_allocate(dma_addr_t* handle)
{
    u32 ret;
   u32 flags;
 
    
    if(g_XC_USBH_info.qh_pool.next == NULL)
    {
        printk("Failed to allocate qh\n");
        while(1);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    *handle = (dma_addr_t)g_XC_USBH_info.qh_pool.next->ehci_qh_hw_seg_paddr;

    ret = (u32) g_XC_USBH_info.qh_pool.next->ehci_qh_hw_seg_vaddr;
    g_XC_USBH_info.qh_pool.next = g_XC_USBH_info.qh_pool.next->next;
    
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
    return ret;
}

EXPORT_SYMBOL(SDUH_qh_hw_seg_allocate);

void SDUH_qh_hw_seg_free(u32 qh_hw_seg_vaddr)
{
    u32 index;
   u32 flags;
 
    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    index = (qh_hw_seg_vaddr - g_XC_USBH_info.qh_hw_seg[0].ehci_qh_hw_seg_vaddr)/EHCI_QH_QTD_SEG_DEFAULT_LEN;

    g_XC_USBH_info.qh_hw_seg[index].next = g_XC_USBH_info.qh_pool.next;
    g_XC_USBH_info.qh_pool.next = &g_XC_USBH_info.qh_hw_seg[index];
        
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);
}

EXPORT_SYMBOL(SDUH_qh_hw_seg_free);


//[JLWang] Here I will assume that All DMA tranfer from USBH are serialized.
//Otherwise A mutex will be needed.

#ifndef USBH_USE_INDIRECT_DMA
unsigned int XCDmaHostToFB (u32 addrSrcHost, u32 addrDestXC, u32 len)
{
    u32 command = 0, temp;

    unsigned long  flags;
 
    if(len > 0x10000)
    {
        printk("ERROR, size is too big %x\n",len);
        return 0;
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    while (temp != (0x80000000|USBH_DMA_INTERLOCK_FUNC_ID))
    {
        spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);        
        msleep(1);
        
        spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);        
        writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
        temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    }
    

    
//    printk("DMA Host %x To FB %x Len %x\n", addrSrcHost, addrDestXC, len);

    command = len;
    command |= VIXS_DMA_DST_FRAME|VIXS_DMA_SRC_SYSTEM;

	
    writel(addrDestXC, g_XC_USBH_info.pmmr + VIXS_DMA_DIRECT_LDST_B);
    writel(addrSrcHost, g_XC_USBH_info.pmmr + VIXS_DMA_DIRECT_LSRC_B);
    writel(command, g_XC_USBH_info.pmmr + VIXS_DMA_DIRECT_DMACMD_B);

    while (readl(g_XC_USBH_info.pmmr + VIXS_DMA_STATUS) & VIXS_DMA_DIRECT_B_MASK);
    


    //unlock mutex if locked
    writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);

//    printk("leaving XCDmaHostToFB\n");

    return len;
}

EXPORT_SYMBOL(XCDmaHostToFB);

unsigned int XCDmaFBToHost (u32 addrSrcXC, u32 addrDestHost, u32 len)
{
    unsigned int command = 0, temp;

    unsigned long  flags;
     if(len > 0x10000)
    {
        printk("ERROR, size is too big %x\n",len);
        return 0;
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
     
    temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    while (temp != (0x80000000|USBH_DMA_INTERLOCK_FUNC_ID))
    {
        spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);        
        msleep(1);
        
        spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);        
        writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
        temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    }

    
//    printk("DMA FB %x To HOST %x\n", addrSrcXC,addrDestHost);

    command = len;
    command |= VIXS_DMA_DST_SYSTEM|VIXS_DMA_SRC_FRAME;

    writel(addrDestHost, g_XC_USBH_info.pmmr + VIXS_DMA_DIRECT_LDST_B);
    writel(addrSrcXC, g_XC_USBH_info.pmmr + VIXS_DMA_DIRECT_LSRC_B);
    writel(command, g_XC_USBH_info.pmmr + VIXS_DMA_DIRECT_DMACMD_B);


    while (readl(g_XC_USBH_info.pmmr + VIXS_DMA_STATUS) & VIXS_DMA_DIRECT_B_MASK);



    //unlock mutex if locked
    writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    
    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);

//    printk("leaving CaminoDmaXCToHost\n");

    return len;
}


EXPORT_SYMBOL(XCDmaFBToHost);

#else// defined USBH_USE_INDIRECT_DMA

unsigned int Vixs_Build_64Bit_Info_To_IO(unsigned int * src, unsigned int * dest, unsigned int size)
{
#if defined(BIG_ENDIAN)
    if (size == sizeof(unsigned int))
    {
       // writel(0, (unsigned int *)dest);
       // writel(*src, (unsigned int *)dest + 1);
       writel(*src, (unsigned int *)dest);
       writel(0, (unsigned int *)dest+1);
    }
    else
    {
        writel(*src, dest + 1);
        writel(*(src+1), (dest));
    }
#else

    writel(*src, dest);

    if (size == sizeof(unsigned long long))
    {
        writel(*(src+1), (dest+1));
    }
    else
    {
        writel(0, (dest+1));
    }
#endif

    return 1;
}

unsigned int XCIndirectDmaHostToFB (u32 addrSrcHost, u32 addrDestXC, u32 len)
{
    unsigned int count = 0, curlen, temp;
    unsigned int command = 0;
    PXC_DMADESCRIPTORS currentDescriptor = NULL;
    unsigned long  flags;

     

    if((len/0x10000) > g_XC_USBH_info.desc_num)
    {
        printk("XCIndirectDmaHostToFB: len %x exceeds the max DMA size %x\n", len, g_XC_USBH_info.desc_num*0x10000);
        return 0;
    }

    temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);

    while (temp != (0x80000000|USBH_DMA_INTERLOCK_FUNC_ID))
    {
        writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
        temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);
    
    //printk("Enter XCIndirectDmaHostToFB\n");
    while(len > 0)
    {

        currentDescriptor = g_XC_USBH_info.pdescriptor + count;

        if(len > 0x10000)
        {
            curlen = 0x10000;
        }
        else
        {
            curlen = len;
        }

        command = len;

        command |= (VIXS_DMA_NOT_EOL|VIXS_DMA_DST_FRAME|VIXS_DMA_SRC_SYSTEM);

        Vixs_Build_64Bit_Info_To_IO(&addrDestXC, (unsigned int *)&currentDescriptor->dst_addr, sizeof(unsigned int));

        Vixs_Build_64Bit_Info_To_IO(&addrSrcHost, (unsigned int *)&currentDescriptor->src_addr, sizeof(unsigned int));

        writel(command, &currentDescriptor->command);
        writel(0, &currentDescriptor->control_word);
				
        count++;
        len -= curlen;
    }

    //point to the last descriptor
    currentDescriptor = g_XC_USBH_info.pdescriptor + (count -1);
    command = readl(&currentDescriptor->command);
    command |= VIXS_DMA_EOL;
    writel(command, &currentDescriptor->command);
    readl(&currentDescriptor->command);
    
    writel(g_XC_USBH_info.descriptor_offset, g_XC_USBH_info.pmmr + VIXS_DMA_DQ_PTR0);

    while (readl(g_XC_USBH_info.pmmr + VIXS_DMA_STATUS) & VIXS_DMA_INDIRECT0_MASK);

    //unlock mutex if locked
    writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);        

    //printk("Exit XCIndirectDmaHostToFB\n");
    return count;
}


unsigned int XCIndirectDmaFBToHost (u32 addrSrcXC, u32 addrDestHost, u32 len)
{
    unsigned int count = 0, curlen, temp;
    unsigned int command = 0;
    PXC_DMADESCRIPTORS currentDescriptor = NULL;
    unsigned long  flags;
    
    if((len/0x10000) > g_XC_USBH_info.desc_num)
    {
        printk("XCIndirectDmaHostToFB: len %x exceeds the max DMA size %x\n", len, g_XC_USBH_info.desc_num*0x10000);
        return 0;
    }
    
    temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    while (temp != (0x80000000|USBH_DMA_INTERLOCK_FUNC_ID))
    {
        writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
        temp = readl (g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);
    }

    spin_lock_irqsave(&sduh_usb_indirect_reg_lock, flags);

    //printk("Enter XCIndirectDmaFBToHost\n");
    while(len > 0)
    {

        currentDescriptor = g_XC_USBH_info.pdescriptor + count;

        if(len > 0x10000)
        {
            curlen = 0x10000;
        }
        else
        {
            curlen = len;
        }

        command = len;
        command |= (VIXS_DMA_NOT_EOL|VIXS_DMA_DST_SYSTEM|VIXS_DMA_SRC_FRAME);

        Vixs_Build_64Bit_Info_To_IO(&addrDestHost, (unsigned int *)&currentDescriptor->dst_addr, sizeof(unsigned int));

        Vixs_Build_64Bit_Info_To_IO(&addrSrcXC, (unsigned int *)&currentDescriptor->src_addr, sizeof(unsigned int));
        writel(command, &currentDescriptor->command);
        writel(0, &currentDescriptor->control_word);
        count++;	
        len -= curlen;
        
    }

    //point to the last descriptor
    currentDescriptor = g_XC_USBH_info.pdescriptor + (count -1);
    command = readl(&currentDescriptor->command);    
    command |= VIXS_DMA_EOL;
    writel(command, &currentDescriptor->command);
    readl(&currentDescriptor->command);
    writel(g_XC_USBH_info.descriptor_offset, g_XC_USBH_info.pmmr + VIXS_DMA_DQ_PTR0);

    while (readl(g_XC_USBH_info.pmmr + VIXS_DMA_STATUS) & VIXS_DMA_INDIRECT0_MASK);

    //unlock mutex if locked
    writel(USBH_DMA_INTERLOCK_FUNC_ID,  g_XC_USBH_info.pmmr + VIXS_USBH_DMA_HW_MUTEX);

    spin_unlock_irqrestore(&sduh_usb_indirect_reg_lock, flags);        

    //printk("Exit XCIndirectDmaFBToHost\n");
    return count;
}

#endif

#define MMR_READ(reg)			readl( (u32 *)(g_XC_USBH_info.pmmr + (reg)) )
#define MMR_WRITE(reg, data)	writel( (data), (u32 *)(((int)g_XC_USBH_info.pmmr) + (reg)) )

static uint XC4115_432pll1_FullSpeed(void)
{
	unsigned int temp_reg_val = 0, temp_reg_val1,temp_reg_val2,temp_reg_val3,temp_reg_val4,temp_reg_val5,temp_reg_val6 ;
	int poll_cnt;
	int poll_limit = 1024;
	int loop_cnt;
	int loop_limit = 16;
	int mem_err = 0;
	int pll_err = 0;
	int pll_state = 0;
	int final_pll_init = 0;

	printk("mem init, XC4115_432pll1_FullSpeed\n");

         /* Eagle_432pll1_fullSpeed_nopll2pll5_4115.c */

        // v.001
        // ----------------------------------------------------------------
        // Automatically generated init settings for XCode IV.
        // Date: Thu Nov 12 18:16:37 2009

        // PLL-Template: profiles/4115/Eagle_432pll1_fullSpeed_nopll2pll5_4115 
        // MC-Template: profiles/Eagle_4115_MT41J64M16LA 
        // ----------------------------------------------------------------


        MMR_WRITE (RBM_SWAP, 0x00000000);
        MMR_WRITE (HOST_INTERRUPT_MASK, 0x00000000);
        MMR_WRITE (MIPS0_INTERRUPT_MASK, 0x00000000);
        MMR_WRITE (MIPS1_INTERRUPT_MASK, 0x00000000);
        MMR_WRITE (MIPS2_INTERRUPT_MASK, 0x00000000);
        MMR_WRITE (MIPS3_INTERRUPT_MASK, 0x00000000);
        MMR_WRITE (MIPS4_INTERRUPT_MASK, 0x00000000);
        MMR_WRITE (HOST_INTERRUPT1_MASK, 0x00000000);
        MMR_WRITE (MIPS0_INTERRUPT1_MASK, 0x00000000);
        MMR_WRITE (MIPS1_INTERRUPT1_MASK, 0x00000000);
        MMR_WRITE (MIPS2_INTERRUPT1_MASK, 0x00000000);
        MMR_WRITE (MIPS3_INTERRUPT1_MASK, 0x00000000);
        MMR_WRITE (MIPS4_INTERRUPT1_MASK, 0x00000000);
        // 
        // Resets all blocks, MCIF rings, PLLs
        MMR_WRITE (CG_CLK_SRC_EN0, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_EN1, 0x00000000);
        MMR_WRITE (CG_CLK_STOP0, 0xc0000000);
        MMR_WRITE (CG_BLK_CLK_STOP0, 0x00000000);
        MMR_WRITE (CG_BLK_CLK_STOP1, 0x00000000);
        MMR_WRITE (CG_BLK_CLK_STOP2, 0x00000000);
        MMR_WRITE (CG_DYNAMIC_BLK_STOP, 0x00000000);
        MMR_WRITE (CG_RESET_REG, 0xfbfff9ff);
        MMR_WRITE (CG_RESET_REG1, 0xfffe7fff);
        MMR_WRITE (CG_MCIF_RESET, 0xffffffff);
        MMR_WRITE (CG_LPCLK_CTRL, 0x01000000);
        MMR_WRITE (CG_CLK_SRC_EN2, 0xbfffffff);
        MMR_WRITE (CG_RESET_REG, 0x00000000);
        MMR_WRITE (CG_RESET_REG1, 0x00000000);
        MMR_WRITE (CG_MCIF_RESET, 0x00000000);
        MMR_WRITE (CG_CLK_STOP0, 0x3fffff82);
        MMR_WRITE (CG_BLK_CLK_STOP0, 0xffffffff);
        MMR_WRITE (CG_BLK_CLK_STOP1, 0xffffffff);
        MMR_WRITE (CG_BLK_CLK_STOP2, 0xffffffff);
        MMR_WRITE (CG_DYNAMIC_BLK_STOP, 0x00000005);
        MMR_WRITE (CG_PLL_MISC_CTRL0, 0x00000003);
        MMR_WRITE (CG_PLL0_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL1_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL2_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL3_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL4_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL5_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL6_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL7_CTRL, 0x00000000);
        MMR_WRITE (CG_I2SSYSCLK_FREQ, 0x01000000);
        MMR_WRITE (CG_MODDIV_CTRL, 0x00000001);
        MMR_WRITE (CG_PWM_CTRL, 0x01000000);
        // 
        // Check PLL state
        MMR_WRITE (RBM_DUMMY_REG, 0x00000000);
        pll_state = ((MMR_READ (RBM_DUMMY_REG) & 0x00100000) == 0x00100000);
        // 
        // Set up clocks.
        MMR_WRITE (CG_LPCLK_CTRL, 0x01010002);
        // Power up bandgap and enable regulator for PLLs
        MMR_WRITE (CG_PLL_MISC_CTRL0, 0x00000001);
        mdelay(1) ; 
        MMR_WRITE (CG_PLL_MISC_CTRL0, 0x00000005);
        mdelay(1) ; 
        MMR_WRITE (CG_PLL_MISC_CTRL0, 0x00000004);
        mdelay(1) ; 
        // Power up and enable PLLs
        loop_cnt = 0;
        while (1) {
        pll_err = 0;
        if (final_pll_init == 1) {
        MMR_WRITE (CG_PLL0_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL1_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL3_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL4_CTRL, 0x04000003);
        MMR_WRITE (CG_PLL6_CTRL, 0x04002003);
        } else if (pll_state == 1) {
        MMR_WRITE (CG_PLL0_CTRL, 0x04002002);
        MMR_WRITE (CG_PLL1_CTRL, 0x04002002);
        MMR_WRITE (CG_PLL3_CTRL, 0x04002002);
        MMR_WRITE (CG_PLL4_CTRL, 0x04000002);
        MMR_WRITE (CG_PLL6_CTRL, 0x04002002);
        mdelay(1) ; 
        MMR_WRITE (CG_PLL0_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL1_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL3_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL4_CTRL, 0x04000003);
        MMR_WRITE (CG_PLL6_CTRL, 0x04002003);
        } else {
        MMR_WRITE (CG_PLL0_CTRL, 0x04002002);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        MMR_WRITE (CG_PLL0_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL1_CTRL, 0x04002002);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        MMR_WRITE (CG_PLL1_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL3_CTRL, 0x04002002);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        MMR_WRITE (CG_PLL3_CTRL, 0x04002003);
        MMR_WRITE (CG_PLL4_CTRL, 0x04000002);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        MMR_WRITE (CG_PLL4_CTRL, 0x04000003);
        MMR_WRITE (CG_PLL6_CTRL, 0x04002002);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        MMR_WRITE (CG_PLL6_CTRL, 0x04002003);
        }
        mdelay(1) ; 
        poll_cnt = 0;
        while ((MMR_READ (CG_PLL_STATUS0) & 0x0000005b) != 0x0000005b) {
        	if (poll_cnt == poll_limit) {
        		pll_err = 1;
        		break;
        	}
        	poll_cnt++;
        }
        // Program the PLL dividers
        MMR_WRITE (CG_PLL0_FREQ, 0x01600000);
        MMR_WRITE (CG_PLL1_FREQ, 0x01000000);
        MMR_WRITE (CG_PLL3_FREQ, 0x01800000);
        MMR_WRITE (CG_PLL4_FREQ, 0x01284bda);
        MMR_WRITE (CG_PLL6_FREQ, 0x01da12f6);
        MMR_WRITE (CG_LPCLK_CTRL, 0x00000002);
        MMR_WRITE (CG_I2SSYSCLK_FREQ, 0x00010004);
        mdelay(1) ; 
        poll_cnt = 0;
        while ((MMR_READ (CG_PLL_STATUS0) & 0x0000005b) != 0x0000005b) {
        	if (poll_cnt == poll_limit) {
        		pll_err = 1;
        		break;
        	}
        	poll_cnt++;
        }

        // Enable fractional dividers
        MMR_WRITE (CG_PLL4_CTRL, 0x06000003);
        MMR_WRITE (CG_PLL6_CTRL, 0x06002003);
        mdelay(1) ; 
        // Set MODDIV to 1024/1125/11 to get 24.576 from 297
        MMR_WRITE (CG_MODDIV_CTRL, 0x00000003);
        MMR_WRITE (CG_MODDIV_CTRL, 0x00000002);
        MMR_WRITE (CG_MODDIV_DEN, 0x00003057);
        MMR_WRITE (CG_MODDIV_NUM, 0x00000400);
        mdelay(1) ; 
        // Power up and enable PLL7
        if (final_pll_init == 1) {
        MMR_WRITE (CG_PLL7_CTRL, 0x04002003);
        } else if (pll_state == 1) {
        MMR_WRITE (CG_PLL7_CTRL, 0x04002002);
        mdelay(1) ; 
        MMR_WRITE (CG_PLL7_CTRL, 0x04002003);
        } else {
        MMR_WRITE (CG_PLL7_CTRL, 0x04002002);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        temp_reg_val = MMR_READ (CG_SYSTEM_CNT);
        MMR_WRITE (CG_PLL7_CTRL, 0x04002003);
        }
        mdelay(1) ; 
        poll_cnt = 0;
        while ((MMR_READ (CG_PLL_STATUS0) & 0x000000db) != 0x000000db) {
        	if (poll_cnt == poll_limit) {
        		pll_err = 1;
        		break;
        	}
        	poll_cnt++;
        }
        // Program the PLL7 dividers
        MMR_WRITE (CG_PLL7_FREQ, 0x015d85e0);
        mdelay(1) ; 
        poll_cnt = 0;
        while ((MMR_READ (CG_PLL_STATUS0) & 0x000000db) != 0x000000db) {
        	if (poll_cnt == poll_limit) {
        		pll_err = 1;
        		break;
        	}
        	poll_cnt++;
        }
        if ((loop_cnt >= loop_limit) & (final_pll_init == 1) & (pll_err == 1)) {
        	printk("Error Code 0-%x\n", MMR_READ(CG_PLL_STATUS0));
        break;}
        if (loop_cnt == loop_limit) {final_pll_init = 1; loop_cnt = 0;}
        if (pll_err == 0) {
        // Disable continuous lock monitor
        MMR_WRITE (CG_PLL0_CTRL, 0x00002003);
        MMR_WRITE (CG_PLL1_CTRL, 0x00002003);
        MMR_WRITE (CG_PLL3_CTRL, 0x00002003);
        MMR_WRITE (CG_PLL4_CTRL, 0x02000003);
        MMR_WRITE (CG_PLL6_CTRL, 0x02002003);
        MMR_WRITE (CG_PLL7_CTRL, 0x02002003);
        break;} else {
        MMR_WRITE (CG_PLL0_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL1_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL3_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL4_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL6_CTRL, 0x00000000);
        MMR_WRITE (CG_PLL7_CTRL, 0x00000000);
        MMR_WRITE (CG_MODDIV_CTRL, 0x00000001);
        }
        loop_cnt++;
        }


        // Choose post-PLL dividers for each of the clocks
        MMR_WRITE (CG_PWM_CTRL, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_SEL0, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_SEL1, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_SEL2, 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_SRC_SEL3);
        MMR_WRITE (CG_CLK_SRC_SEL3, (temp_reg_val & 0x00000000) | 0x00000000);
        MMR_WRITE (CG_CLK_SRC_SEL4, 0x00a00010);
        MMR_WRITE (CG_CLK_SRC_SEL5, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_SEL6, 0x00008080);
        MMR_WRITE (CG_CLK_SRC_SEL7, 0x00003000);
        MMR_WRITE (CG_CLK_SRC_SEL9, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_SEL10, 0x00301000);
        MMR_WRITE (CG_CLK_SRC_SEL11, 0xc0000060);
        // Switch some clocks to PLL
        if (pll_err) {
        MMR_WRITE (CG_CLK_SRC_EN0, 0x00000000);
        MMR_WRITE (CG_CLK_SRC_EN1, 0x00000000);
        } else {
        MMR_WRITE (CG_CLK_SRC_EN0, 0x1a3fddef);
        MMR_WRITE (CG_CLK_SRC_EN1, 0x00001a66);
        }
        // 
        // Calculating frequency for each PLL
        // PLL0 perid is 1.683502 ns. (594.000000 MHz)
        // PLL1 perid is 2.314815 ns. (432.000000 MHz)
        // PLL2 perid is 0.000000 ns. (inf    MHz)
        // PLL3 perid is 1.543210 ns. (648.000000 MHz)
        // PLL4 perid is 2.000000 ns. (499.999998 MHz)
        // PLL5 perid is 0.000000 ns. (inf    MHz)
        // PLL6 perid is 1.250000 ns. (799.999987 MHz)
        // PLL7 perid is 1.695433 ns. (589.819977 MHz)
        // 
        // Calculating clock speeds:
        // LPCLK period is 74.074074 ns. (13.500000 MHz)
        // 0) MCLK period is 4.629630 ns. (216.000000 MHz)
        // 1) SCLK period is 6.172840 ns. (162.000000 MHz)
        // 2) SEQ0CLK period is 2.314815 ns. (432.000000 MHz)
        // 3) SEQ1CLK period is 2.314815 ns. (432.000000 MHz)
        // 4) CALCLK period is 37.037037 ns. (27.000000 MHz)
        // 5) MRCLK period is 9.259259 ns. (108.000000 MHz)
        // 6) XCLK period is 37.037037 ns. (27.000000 MHz)
        // 7) BCLK period is 9.259259 ns. (108.000000 MHz)
        // 8) DCLK period is 7.716049 ns. (129.600000 MHz)
        // 9) ECLK period is 3.367003 ns. (297.000000 MHz)
        // 10) VCLK period is 3.367003 ns. (297.000000 MHz)
        // 11) CCLK period is 30.000001 ns. (33.333333 MHz)
        // 12) UCLK period is 37.037037 ns. (27.000000 MHz)
        // 13) HUECLK period is 7.716049 ns. (129.600000 MHz)
        // 14) GVPCLK period is 3.367003 ns. (297.000000 MHz)
        // 15) GVDCLK period is 4.000000 ns. (249.999999 MHz)
        // 16) P0CLK period is 3.367003 ns. (297.000000 MHz)
        // 17) P1CLK period is 3.367003 ns. (297.000000 MHz)
        // 18) P2CLK period is 2.000000 ns. (499.999998 MHz)
        // 19) P3CLK period is 2.000000 ns. (499.999998 MHz)
        // 20) P4CLK period is 2.500000 ns. (399.999993 MHz)
        // 21) I2SSYSCLK period is 74.074074 ns. (13.500000 MHz)
        // 22) SATACLK period is 16.000000 ns. (62.500000 MHz)
        // 23) ETHR0CLK period is 40.000000 ns. (25.000000 MHz)
        // 24) ECCCLK period is 6.734007 ns. (148.500000 MHz)
        // 25) DMACLK period is 5.000000 ns. (199.999997 MHz)
        // 26) BCLK1 period is 9.259259 ns. (108.000000 MHz)
        // 27) HCLK period is 3.086420 ns. (324.000000 MHz)
        // 28) FCLK period is 4.000000 ns. (249.999999 MHz)
        // 29) SMCCCLK period is 40.123457 ns. (24.923077 MHz)
        // 30) FREECLK period is 37.037037 ns. (27.000000 MHz)
        // 
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xfeffffff) | 0x01000000);
        // Deassert the IO reset. Channel: 0
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xfffff7ff) | 0x00000800);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xfffffffb) | 0x00000004);
        // Start IO Calibration channel
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xfffffaff) | 0x00000500);
        // Deassert the PHY reset and let DLLs lock
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xfffffdff) | 0x00000200);
        // Setting up VRG Sequencer Registers
        MMR_WRITE (SEQ_CH0_ADDRMAP1, 0xfff00000);
        MMR_WRITE (SEQ_CH0_ADDRMAP0, 0x00000777);
        MMR_WRITE (SEQ_CH0_ADDRMAP2, 0x0f333333);
        temp_reg_val = MMR_READ (SEQ_CH0_INIT0);
        MMR_WRITE (SEQ_CH0_INIT0, (temp_reg_val & 0xffffff00) | 0x000000d3);
        temp_reg_val = MMR_READ (SEQ_CH0_INIT1);
        MMR_WRITE (SEQ_CH0_INIT1, (temp_reg_val & 0xffffff00) | 0x00000055);
        temp_reg_val = MMR_READ (SEQ_CH0_ZQ0);
        MMR_WRITE (SEQ_CH0_ZQ0, (temp_reg_val & 0xbfc00c00) | 0x00100020);
        MMR_WRITE (SEQ_CH0_ZQ1, 0x00006978);
        temp_reg_val = MMR_READ (SEQ_CH0_INIT2);
        MMR_WRITE (SEQ_CH0_INIT2, (temp_reg_val & 0xfdb9f18c) | 0x00440630);
        temp_reg_val = MMR_READ (SEQ_CH0_INIT3);
        MMR_WRITE (SEQ_CH0_INIT3, (temp_reg_val & 0xffffffc7) | 0x00000008);
        MMR_WRITE (SEQ_CH0_TIMING0, 0x39142c0c);
        MMR_WRITE (SEQ_CH0_TIMING1, 0x93270343);
        MMR_WRITE (SEQ_CH0_TIMING2, 0x31e6610b);
        temp_reg_val = MMR_READ (SEQ_CH0_TIMING3);
        MMR_WRITE (SEQ_CH0_TIMING3, (temp_reg_val & 0xc7cf0f0f) | 0x10105000);
        temp_reg_val = MMR_READ (SEQ_CH0_TRAN_CTRL3);
        MMR_WRITE (SEQ_CH0_TRAN_CTRL3, (temp_reg_val & 0xf7ff03ff) | 0x0000e000);
        temp_reg_val = MMR_READ (SEQ_CH0_REFRESH);
        MMR_WRITE (SEQ_CH0_REFRESH, (temp_reg_val & 0xfffffff8) | 0x00000007);
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0xffff0000) | 0x0000ffff);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH0_PHY_MISC_REG, (temp_reg_val & 0xffffffdf) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_CTRL0);
        MMR_WRITE (SEQ_CH0_PHY_CTRL0, (temp_reg_val & 0xfffff060) | 0x00000307);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE0_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE0_B, 0x00005000);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE1_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE1_B, 0x00005000);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE2_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE2_B, 0x00005000);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE3_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQ_BYTE3_B, 0x00005000);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE0_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE0_B, 0x00008000);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE1_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE1_B, 0x00008000);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE2_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE2_B, 0x00008000);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE3_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_DQS_BYTE3_B, 0x00008000);
        MMR_WRITE (SEQ_CH0_IO_ADR_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_ADR_B, 0x00001000);
        MMR_WRITE (SEQ_CH0_IO_CMD_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_CMD_B, 0x00001000);
        MMR_WRITE (SEQ_CH0_IO_CLK_A, 0x00f33336);
        MMR_WRITE (SEQ_CH0_IO_CLK_B, 0x00001000);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xfeffffff) | 0x01000000);
        // Deassert the IO reset. Channel: 1
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xfffff7ff) | 0x00000800);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xfffffffb) | 0x00000004);
        // Start IO Calibration channel
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xfffffaff) | 0x00000500);
        // Deassert the PHY reset and let DLLs lock
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xfffffdff) | 0x00000200);
        // Setting up VRG Sequencer Registers
        MMR_WRITE (SEQ_CH1_ADDRMAP1, 0xfff00000);
        MMR_WRITE (SEQ_CH1_ADDRMAP0, 0x00000777);
        MMR_WRITE (SEQ_CH1_ADDRMAP2, 0x0f333333);
        temp_reg_val = MMR_READ (SEQ_CH1_INIT0);
        MMR_WRITE (SEQ_CH1_INIT0, (temp_reg_val & 0xffffff00) | 0x000000d3);
        temp_reg_val = MMR_READ (SEQ_CH1_INIT1);
        MMR_WRITE (SEQ_CH1_INIT1, (temp_reg_val & 0xffffff00) | 0x00000055);
        temp_reg_val = MMR_READ (SEQ_CH1_ZQ0);
        MMR_WRITE (SEQ_CH1_ZQ0, (temp_reg_val & 0xbfc00c00) | 0x00100020);
        MMR_WRITE (SEQ_CH1_ZQ1, 0x00006978);
        temp_reg_val = MMR_READ (SEQ_CH1_INIT2);
        MMR_WRITE (SEQ_CH1_INIT2, (temp_reg_val & 0xfdb9f18c) | 0x00440630);
        temp_reg_val = MMR_READ (SEQ_CH1_INIT3);
        MMR_WRITE (SEQ_CH1_INIT3, (temp_reg_val & 0xffffffc7) | 0x00000008);
        MMR_WRITE (SEQ_CH1_TIMING0, 0x39142c0c);
        MMR_WRITE (SEQ_CH1_TIMING1, 0x93270343);
        MMR_WRITE (SEQ_CH1_TIMING2, 0x31e6610b);
        temp_reg_val = MMR_READ (SEQ_CH1_TIMING3);
        MMR_WRITE (SEQ_CH1_TIMING3, (temp_reg_val & 0xc7cf0f0f) | 0x10105000);
        temp_reg_val = MMR_READ (SEQ_CH1_TRAN_CTRL3);
        MMR_WRITE (SEQ_CH1_TRAN_CTRL3, (temp_reg_val & 0xf7ff03ff) | 0x0000e000);
        temp_reg_val = MMR_READ (SEQ_CH1_REFRESH);
        MMR_WRITE (SEQ_CH1_REFRESH, (temp_reg_val & 0xfffffff8) | 0x00000007);
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0xffff0000) | 0x0000ffff);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH1_PHY_MISC_REG, (temp_reg_val & 0xffffffdf) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_CTRL0);
        MMR_WRITE (SEQ_CH1_PHY_CTRL0, (temp_reg_val & 0xfffff060) | 0x00000307);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE0_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE0_B, 0x00005000);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE1_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE1_B, 0x00005000);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE2_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE2_B, 0x00005000);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE3_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQ_BYTE3_B, 0x00005000);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE0_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE0_B, 0x00008000);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE1_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE1_B, 0x00008000);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE2_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE2_B, 0x00008000);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE3_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_DQS_BYTE3_B, 0x00008000);
        MMR_WRITE (SEQ_CH1_IO_ADR_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_ADR_B, 0x00001000);
        MMR_WRITE (SEQ_CH1_IO_CMD_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_CMD_B, 0x00001000);
        MMR_WRITE (SEQ_CH1_IO_CLK_A, 0x00f33336);
        MMR_WRITE (SEQ_CH1_IO_CLK_B, 0x00001000);
        // Waiting for DLL to lock
        while ((MMR_READ (SEQ_CH0_PHY_STATUS) & 0x000000c0) != 0x000000c0);
        // DLL Locked
        // Waiting for DLL to lock
        while ((MMR_READ (SEQ_CH1_PHY_STATUS) & 0x000000c0) != 0x000000c0);
        // DLL Locked
        temp_reg_val = MMR_READ (SEQ_CH0_IOCALIB_CTRL);
        MMR_WRITE (SEQ_CH0_IOCALIB_CTRL, (temp_reg_val & 0xfff9ffff) | 0x00020000);
        while ((MMR_READ (SEQ_CH0_IOCALIB_STATUS) & 0xffff0000) != 0x11110000);
        temp_reg_val2 = MMR_READ (SEQ_CH0_IOCALIB_STATUS);
        temp_reg_val = MMR_READ (SEQ_CH0_IOCALIB_CTRL);
        MMR_WRITE (SEQ_CH0_IOCALIB_CTRL, (temp_reg_val & ~0x000FFFF) | ((temp_reg_val2 & 0xFFFF) & 0x000FFFF));
        temp_reg_val = MMR_READ (SEQ_CH0_IOCALIB_CTRL);
        MMR_WRITE (SEQ_CH0_IOCALIB_CTRL, (temp_reg_val & 0xfffeffff) | 0x00010000);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x4c000000);
        temp_reg_val2 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x48000000);
        temp_reg_val4 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_CTRL1);
        MMR_WRITE (SEQ_CH0_PHY_CTRL1, (temp_reg_val & ~0x0000FE00) | (((((temp_reg_val2 & 0x0000000F) << 8 ) | (((temp_reg_val4 & 0xFF000000) >> 24) & 0x000000FF)) * 35/100 ) << 9  & 0x0000FE00));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_CTRL1);
        MMR_WRITE (SEQ_CH0_PHY_CTRL1, (temp_reg_val & 0xfffffeff) | 0x00000100);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_CTRL1);
        MMR_WRITE (SEQ_CH0_PHY_CTRL1, (temp_reg_val & 0xffffff00) | 0x00000000);
        // Bringing VRG IP IN SEQUENCER OUT OF RESET
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xffffffdf) | 0x00000020);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xffffffbf) | 0x00000040);
        temp_reg_val = MMR_READ (SEQ_CH1_IOCALIB_CTRL);
        MMR_WRITE (SEQ_CH1_IOCALIB_CTRL, (temp_reg_val & 0xfff9ffff) | 0x00020000);
        while ((MMR_READ (SEQ_CH1_IOCALIB_STATUS) & 0xffff0000) != 0x11110000);
        temp_reg_val2 = MMR_READ (SEQ_CH1_IOCALIB_STATUS);
        temp_reg_val = MMR_READ (SEQ_CH1_IOCALIB_CTRL);
        MMR_WRITE (SEQ_CH1_IOCALIB_CTRL, (temp_reg_val & ~0x000FFFF) | ((temp_reg_val2 & 0xFFFF) & 0x000FFFF));
        temp_reg_val = MMR_READ (SEQ_CH1_IOCALIB_CTRL);
        MMR_WRITE (SEQ_CH1_IOCALIB_CTRL, (temp_reg_val & 0xfffeffff) | 0x00010000);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x50000000);
        temp_reg_val2 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x4c000000);
        temp_reg_val4 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_CTRL1);
        MMR_WRITE (SEQ_CH1_PHY_CTRL1, (temp_reg_val & ~0x0000FE00) | (((((temp_reg_val2 & 0x000000FF) << 4 ) | (((temp_reg_val4 & 0xF0000000) >> 28) & 0x0000000F)) * 20/100 ) << 9  & 0x0000FE00));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_CTRL1);
        MMR_WRITE (SEQ_CH1_PHY_CTRL1, (temp_reg_val & 0xfffffeff) | 0x00000100);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_CTRL1);
        MMR_WRITE (SEQ_CH1_PHY_CTRL1, (temp_reg_val & 0xffffff00) | 0x00000000);
        // Bringing VRG IP IN SEQUENCER OUT OF RESET
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xffffffdf) | 0x00000020);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xffffffbf) | 0x00000040);
        // Initializing MC Channel 0, 1....
        MMR_WRITE (MC_CONFIG_REG, 0x0000001c);
        MMR_WRITE (MC_CH0_MEM_CONFIG, 0x00000537);
        MMR_WRITE (MC_CH0_ARB_CTRLA, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_CTRLB, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_PAGE_TIMER_CTRLA, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_PAGE_TIMER_CTRLB, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_LATENCY_TIMER_CTRLA, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_LATENCY_TIMER_CTRLB, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_LATENCY_TIMER_CTRLC, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_LATENCY_TIMER_CTRLD, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_MAIN_CTRL, 0x20000000);
        MMR_WRITE (MC_CH0_ARB_PRIORITY_CTRLA, 0x00000000);
        MMR_WRITE (MC_CH0_ARB_PRIORITY_CTRLB, 0x00000000);
        MMR_WRITE (MC_CH0_ARB_PRIORITY_CTRLC, 0xffffffff);
        MMR_WRITE (MC_CH0_ARB_PRIORITY_CTRLD, 0xffffffff);
        MMR_WRITE (MC_CH1_MEM_CONFIG, 0x00000537);
        MMR_WRITE (MC_CH1_ARB_CTRLA, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_CTRLB, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_PAGE_TIMER_CTRLA, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_PAGE_TIMER_CTRLB, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_LATENCY_TIMER_CTRLA, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_LATENCY_TIMER_CTRLB, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_LATENCY_TIMER_CTRLC, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_LATENCY_TIMER_CTRLD, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_MAIN_CTRL, 0x20000000);
        MMR_WRITE (MC_CH1_ARB_PRIORITY_CTRLA, 0x00000000);
        MMR_WRITE (MC_CH1_ARB_PRIORITY_CTRLB, 0x00000000);
        MMR_WRITE (MC_CH1_ARB_PRIORITY_CTRLC, 0xffffffff);
        MMR_WRITE (MC_CH1_ARB_PRIORITY_CTRLD, 0xffffffff);
        // Waiting for VRG Seq to finish SDRAM initialization
        while ((MMR_READ (SEQ_CH0_VRG_STATUS) & 0x00000003) != 0x00000001);
        // Finished SDRAM Initialization
        // Waiting for VRG Seq to finish SDRAM initialization
        while ((MMR_READ (SEQ_CH1_VRG_STATUS) & 0x00000003) != 0x00000001);
        // Finished SDRAM Initialization
        // DDR3 Disable ZQ, Refresh, DLL calib for leveling channel=0
        temp_reg_val = MMR_READ (SEQ_CH0_ZQ0);
        MMR_WRITE (SEQ_CH0_ZQ0, (temp_reg_val & 0xbfffffff) | 0x40000000);
        temp_reg_val = MMR_READ (SEQ_CH0_REFRESH);
        MMR_WRITE (SEQ_CH0_REFRESH, (temp_reg_val & 0xbfffffff) | 0x40000000);
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0x3fffffff) | 0xc0000000);
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0x3fffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE2_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE2_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE3_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE3_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_3);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_3, (temp_reg_val & 0xfffffffe) | 0x00000001);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_3);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_3, (temp_reg_val & 0xfffffffe) | 0x00000001);
        // DDR3 WR leveling channel=40c6160
        MMR_WRITE (SEQ_CH0_WRITE_MR, 0x000100c4);
        while ((MMR_READ (SEQ_CH0_VRG_STATUS) & 0x00800000) != 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH0_PHY_MISC_REG, (temp_reg_val & 0xffffff7f) | 0x00000080);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH0_PHY_MISC_REG, (temp_reg_val & 0xffffff7f) | 0x00000000);
        while ((MMR_READ (SEQ_CH0_PHY_STATUS) & 0x00000010) != 0x00000010);
        MMR_WRITE (SEQ_CH0_WRITE_MR, 0x00010044);
        while ((MMR_READ (SEQ_CH0_VRG_STATUS) & 0x00800000) != 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_3);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_3, (temp_reg_val & 0xfffffffe) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_3);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_3, (temp_reg_val & 0xfffffffe) | 0x00000000);
        // Issue the DLL calib
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0x3fffffff) | 0xc0000000);
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0x3fffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE2_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE2_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE3_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE3_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x68000000);
        temp_reg_val1 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x64000000);
        temp_reg_val2 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x60000000);
        temp_reg_val3 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x5c000000);
        temp_reg_val4 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x54000000);
        temp_reg_val6 = MMR_READ (SEQ_CH0_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE2_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE2_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE3_0);
        MMR_WRITE (SEQ_CH0_PHY_SLICE3_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_1);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_1, (temp_reg_val & ~0x000000FF) | (((temp_reg_val1 & 0x00FF0000) >> 16)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_1);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_1, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val2 & 0x0000000F) << 4) | (((temp_reg_val3 & 0xF0000000) >> 28) & 0x0000000F))<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE2_1);
        MMR_WRITE (SEQ_CH0_PHY_SLICE2_1, (temp_reg_val & ~0x000000FF) | (((temp_reg_val4 & 0x0000FF00) >> 8)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE3_1);
        MMR_WRITE (SEQ_CH0_PHY_SLICE3_1, (temp_reg_val & ~0x000000FF) | (((temp_reg_val6 & 0x0FF00000) >> 20)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_2);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_2, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val1 & 0x00FF0000) >> 16)+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_2);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_2, (temp_reg_val & ~0x000000FF) | (((((temp_reg_val2 & 0x0000000F) << 4) | (((temp_reg_val3 & 0xF0000000) >> 28) & 0x0000000F))+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE2_2);
        MMR_WRITE (SEQ_CH0_PHY_SLICE2_2, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val4 & 0x0000FF00) >> 8)+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE3_2);
        MMR_WRITE (SEQ_CH0_PHY_SLICE3_2, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val6 & 0x0FF00000) >> 20)+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE0_3);
        MMR_WRITE (SEQ_CH0_PHY_SLICE0_3, (temp_reg_val & ~0x0000FF01) | (((((temp_reg_val1 & 0x00FF0000) >> 16)+(((temp_reg_val2 & 0x0000000F) << 4) | (((temp_reg_val3 & 0xF0000000) >> 28) & 0x0000000F)))/2 + 0x41)<<8 | 0x1<<0 & 0x0000FF01));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_SLICE1_3);
        MMR_WRITE (SEQ_CH0_PHY_SLICE1_3, (temp_reg_val & ~0x0000FF01) | (((((temp_reg_val4 & 0x0000FF00) >> 8)+((temp_reg_val6 & 0x0FF00000) >> 20))/2 + 0x41)<<8 | 0x1<<0 & 0x0000FF01));
        temp_reg_val = MMR_READ (SEQ_CH0_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH0_PHY_MISC_REG, (temp_reg_val & 0xfffffffb) | 0x00000004);
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0x3fffffff) | 0xc0000000);
        temp_reg_val = MMR_READ (SEQ_CH0_DLL);
        MMR_WRITE (SEQ_CH0_DLL, (temp_reg_val & 0x3fffffff) | 0x00000000);
        // DDR3 Enable ZQ, Refresh, Do DLL Calib after leveling
        temp_reg_val = MMR_READ (SEQ_CH0_ZQ0);
        MMR_WRITE (SEQ_CH0_ZQ0, (temp_reg_val & 0xbfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_REFRESH);
        MMR_WRITE (SEQ_CH0_REFRESH, (temp_reg_val & 0xbfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH0_TIMING4);
        MMR_WRITE (SEQ_CH0_TIMING4, (temp_reg_val & 0xfffff800) | 0x00000182);
        // Bringing CTRLWRAP (mrclk, mclk, seqclk) and IPWRAP (seqclk) LOGIC OUT OF RESET
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xffffffef) | 0x00000010);
        temp_reg_val = MMR_READ (SEQ_CH0_MISC_REG_0);
        MMR_WRITE (SEQ_CH0_MISC_REG_0, (temp_reg_val & 0xfffffffc) | 0x00000003);
        // DDR3 Disable ZQ, Refresh, DLL calib for leveling channel=1
        temp_reg_val = MMR_READ (SEQ_CH1_ZQ0);
        MMR_WRITE (SEQ_CH1_ZQ0, (temp_reg_val & 0xbfffffff) | 0x40000000);
        temp_reg_val = MMR_READ (SEQ_CH1_REFRESH);
        MMR_WRITE (SEQ_CH1_REFRESH, (temp_reg_val & 0xbfffffff) | 0x40000000);
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0x3fffffff) | 0xc0000000);
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0x3fffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE2_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE2_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE3_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE3_0, (temp_reg_val & 0xff00ffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_3);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_3, (temp_reg_val & 0xfffffffe) | 0x00000001);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_3);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_3, (temp_reg_val & 0xfffffffe) | 0x00000001);
        // DDR3 WR leveling channel=40c6161
        MMR_WRITE (SEQ_CH1_WRITE_MR, 0x000100c4);
        while ((MMR_READ (SEQ_CH1_VRG_STATUS) & 0x00800000) != 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH1_PHY_MISC_REG, (temp_reg_val & 0xffffff7f) | 0x00000080);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH1_PHY_MISC_REG, (temp_reg_val & 0xffffff7f) | 0x00000000);
        while ((MMR_READ (SEQ_CH1_PHY_STATUS) & 0x00000010) != 0x00000010);
        MMR_WRITE (SEQ_CH1_WRITE_MR, 0x00010044);
        while ((MMR_READ (SEQ_CH1_VRG_STATUS) & 0x00800000) != 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_3);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_3, (temp_reg_val & 0xfffffffe) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_3);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_3, (temp_reg_val & 0xfffffffe) | 0x00000000);
        // Issue the DLL calib
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0x3fffffff) | 0xc0000000);
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0x3fffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE2_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE2_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE3_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE3_0, (temp_reg_val & 0xff00ffff) | 0x00300000);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x68000000);
        temp_reg_val1 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x64000000);
        temp_reg_val2 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x60000000);
        temp_reg_val3 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x5c000000);
        temp_reg_val4 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0x03ffffff) | 0x54000000);
        temp_reg_val6 = MMR_READ (SEQ_CH1_DEBUG_BUS);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE2_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE2_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE3_0);
        MMR_WRITE (SEQ_CH1_PHY_SLICE3_0, (temp_reg_val & 0xffffff00) | 0x00000041);
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_1);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_1, (temp_reg_val & ~0x000000FF) | (((temp_reg_val1 & 0x00FF0000) >> 16)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_1);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_1, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val2 & 0x0000000F) << 4) | (((temp_reg_val3 & 0xF0000000) >> 28) & 0x0000000F))<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE2_1);
        MMR_WRITE (SEQ_CH1_PHY_SLICE2_1, (temp_reg_val & ~0x000000FF) | (((temp_reg_val4 & 0x0000FF00) >> 8)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE3_1);
        MMR_WRITE (SEQ_CH1_PHY_SLICE3_1, (temp_reg_val & ~0x000000FF) | (((temp_reg_val6 & 0x0FF00000) >> 20)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_2);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_2, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val1 & 0x00FF0000) >> 16)+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_2);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_2, (temp_reg_val & ~0x000000FF) | (((((temp_reg_val2 & 0x0000000F) << 4) | (((temp_reg_val3 & 0xF0000000) >> 28) & 0x0000000F))+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE2_2);
        MMR_WRITE (SEQ_CH1_PHY_SLICE2_2, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val4 & 0x0000FF00) >> 8)+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE3_2);
        MMR_WRITE (SEQ_CH1_PHY_SLICE3_2, (temp_reg_val & ~0x000000FF) | ((((temp_reg_val6 & 0x0FF00000) >> 20)+0x40)<<0 & 0x000000FF));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE0_3);
        MMR_WRITE (SEQ_CH1_PHY_SLICE0_3, (temp_reg_val & ~0x0000FF01) | (((((temp_reg_val1 & 0x00FF0000) >> 16)+(((temp_reg_val2 & 0x0000000F) << 4) | (((temp_reg_val3 & 0xF0000000) >> 28) & 0x0000000F)))/2 + 0x41)<<8 | 0x1<<0 & 0x0000FF01));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_SLICE1_3);
        MMR_WRITE (SEQ_CH1_PHY_SLICE1_3, (temp_reg_val & ~0x0000FF01) | (((((temp_reg_val4 & 0x0000FF00) >> 8)+((temp_reg_val6 & 0x0FF00000) >> 20))/2 + 0x41)<<8 | 0x1<<0 & 0x0000FF01));
        temp_reg_val = MMR_READ (SEQ_CH1_PHY_MISC_REG);
        MMR_WRITE (SEQ_CH1_PHY_MISC_REG, (temp_reg_val & 0xfffffffb) | 0x00000004);
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0x3fffffff) | 0xc0000000);
        temp_reg_val = MMR_READ (SEQ_CH1_DLL);
        MMR_WRITE (SEQ_CH1_DLL, (temp_reg_val & 0x3fffffff) | 0x00000000);
        // DDR3 Enable ZQ, Refresh, Do DLL Calib after leveling
        temp_reg_val = MMR_READ (SEQ_CH1_ZQ0);
        MMR_WRITE (SEQ_CH1_ZQ0, (temp_reg_val & 0xbfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_REFRESH);
        MMR_WRITE (SEQ_CH1_REFRESH, (temp_reg_val & 0xbfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (SEQ_CH1_TIMING4);
        MMR_WRITE (SEQ_CH1_TIMING4, (temp_reg_val & 0xfffff800) | 0x00000182);
        // Bringing CTRLWRAP (mrclk, mclk, seqclk) and IPWRAP (seqclk) LOGIC OUT OF RESET
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xffffffef) | 0x00000010);
        temp_reg_val = MMR_READ (SEQ_CH1_MISC_REG_0);
        MMR_WRITE (SEQ_CH1_MISC_REG_0, (temp_reg_val & 0xfffffffc) | 0x00000003);
        // Bringing MD/MRCLK LOGIC OUT OF RESET
        temp_reg_val = MMR_READ (MC_MISC_REG);
        MMR_WRITE (MC_MISC_REG, (temp_reg_val & 0xfffffffe) | 0x00000001);
        // Polling for INIT RDY bit
        while ((MMR_READ (MC_STATUS) & 0x00000001) != 0x00000001);
        // Initialization complete
        MMR_WRITE (RBM_SWAP, 0x00020000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffffffe) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffffffb) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffffff7) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffffef) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffffdf) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffffbf) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffff7f) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffffeff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffffbff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffff7ff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffefff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffdfff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffffbfff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffff7fff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffeffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffdffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfffbffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfff7ffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffefffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xffdfffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xfdffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xf7ffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xefffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0xbfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_CLK_STOP0);
        MMR_WRITE (CG_CLK_STOP0, (temp_reg_val & 0x7fffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffffffe) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffffffb) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffffff7) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffffffef) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffffffdf) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffffffbf) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffffff7f) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffffeff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffffdff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffffbff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffff7ff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffeffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffdffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfffbffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfff7ffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffefffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffdfffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xffbfffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xff7fffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfeffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfdffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xfbffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xf7ffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0xdfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP0);
        MMR_WRITE (CG_BLK_CLK_STOP0, (temp_reg_val & 0x7fffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xfffffffe) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xfffffffb) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xfffffff7) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xffffffef) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xffffffdf) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xfffff7ff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xffffdfff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xffffbfff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xfffbffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xfff7ffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xffefffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xefffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xdfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP1);
        MMR_WRITE (CG_BLK_CLK_STOP1, (temp_reg_val & 0xbfffffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xffffff7f) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xfffffeff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xfffffdff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xfffff7ff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xfffbffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xffefffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xffbfffff) | 0x00000000);
        temp_reg_val = MMR_READ (CG_BLK_CLK_STOP2);
        MMR_WRITE (CG_BLK_CLK_STOP2, (temp_reg_val & 0xff7fffff) | 0x00000000);


        printk("XCODE MEMORY INITIALZATION LEAVE !!!!!!!!!!!!! \n");
	if (pll_err || mem_err)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}



int XC_USBH_Global_Struct_Init(void)
{
    struct pci_dev *dev = NULL;
    u32 physMemAddr;
    u32 physMemSize;
    u32 temp, count;

    if(g_XC_USBH_Global_Struct_Initialized)
    {
        printk(" XC USBH Global Struct has been initialized already\n");
        return 0;
    }

    memset(&g_XC_USBH_info, 0, sizeof(g_XC_USBH_info));

    //find XCode PCI device and get FB mem base and REG base

       
    dev = pci_find_device(VIXS_PCI_VENDOR_ID, XCODE4_PCI_DEVICE_ID, NULL);
        
    if (NULL == dev)
    {
        printk("FAILED to find Vendor Id: %Xh and device ID %Xh\n",
                                                    VIXS_PCI_VENDOR_ID, XCODE4_PCI_DEVICE_ID);
        return -ENODEV;
    }

    g_XC_USBH_info.ppcidev = dev;
    
    pci_enable_device(dev);


    //step through and get all the BARs
    for (count = 0; count < TotalBAR; count ++)
    {
        temp = pci_resource_flags(dev, count);

        if (temp & IORESOURCE_IO)
        {
            //ignore
        }
        else if(temp & IORESOURCE_MEM)
        {
            physMemAddr = pci_resource_start (dev, (u32) count);
            temp = pci_resource_end (dev, (u32) count);
            physMemSize = temp - physMemAddr;

            if (physMemSize > 0x10000) //64K
            {
                //MMFB
                g_XC_USBH_info.physfb = physMemAddr;
                g_XC_USBH_info.fbsize = physMemSize;
                g_XC_USBH_info.pmmfb = ioremap_nocache(physMemAddr, physMemSize);

                printk("BAR%x phys addr 0x%08x lin. addr 0x%08x size 0x%08x\n",
                                                    (u32)count,
                                                    (u32)g_XC_USBH_info.physfb,
                                                    (u32)g_XC_USBH_info.pmmfb,
                                                    (u32)g_XC_USBH_info.fbsize);
            }
            else
            {
                //MMR
                if(g_XC_USBH_info.physmmr)
                {
                    printk("MMR is valid already, ignore this bar\n");
                }
                else
                {
                    //MMR
                    g_XC_USBH_info.physmmr = physMemAddr;
                    g_XC_USBH_info.mmrsize = physMemSize;
                    g_XC_USBH_info.pmmr = ioremap_nocache(physMemAddr, physMemSize);
    				
                    printk("BAR%x phys addr 0x%08x lin. addr 0x%08x size 0x%08x\n",
                                                        (u32)count,
                                                        (u32)g_XC_USBH_info.physmmr,
                                                        (u32)g_XC_USBH_info.pmmr,
                                                        (u32)g_XC_USBH_info.mmrsize);
                }
            }
        }
    }


      g_XC_USBH_info.Pci_Interrupt_Line = dev->irq;

    //Initialize memory
    temp = MMR_READ (RBM_SWAP);
    if(temp & MC_INIT_MASK)
    {
    }
    else
    {
        printk("XCode Memory has not been initialized, please install AV driver first\n");
//        return -ENODEV;
        
        XC4115_432pll1_FullSpeed();  
    }

       
    spin_lock_init(&sduh_usb_indirect_reg_lock);

    //Inlitialize memory based structures
    g_XC_USBH_info.echi_periodic_mem_paddr = /*0xC0000000 + */EHCI_PERIODIC_MEM_OFFSET;
    g_XC_USBH_info.echi_periodic_mem_vaddr = g_XC_USBH_info.pmmfb + EHCI_PERIODIC_MEM_OFFSET;

    for(count = 0; count < EHCI_QH_QUEUE_ITEM_NUM; count++)
    {
        g_XC_USBH_info.qh_hw_seg[count].ehci_qh_hw_seg_paddr = /*0xC0000000 + */EHCI_QH_HW_SEG_MEM_OFFSET + EHCI_QH_QTD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.qh_hw_seg[count].ehci_qh_hw_seg_vaddr = g_XC_USBH_info.pmmfb + EHCI_QH_HW_SEG_MEM_OFFSET + EHCI_QH_QTD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.qh_hw_seg[count].status = 0;
        g_XC_USBH_info.qh_hw_seg[count].next = &g_XC_USBH_info.qh_hw_seg[count+1];
    }
    g_XC_USBH_info.qh_hw_seg[EHCI_QH_QUEUE_ITEM_NUM-1].next = NULL;
    g_XC_USBH_info.qh_pool.next = &g_XC_USBH_info.qh_hw_seg[0];

    for(count = 0; count < EHCI_QTD_QUEUE_ITEM_NUM; count++)
    {
        g_XC_USBH_info.qtd_hw_seg[count].ehci_qtd_hw_seg_paddr = /*0xC0000000 + */EHCI_QTD_HW_SEG_MEM_OFFSET + EHCI_QH_QTD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.qtd_hw_seg[count].ehci_qtd_hw_seg_vaddr = g_XC_USBH_info.pmmfb + EHCI_QTD_HW_SEG_MEM_OFFSET + EHCI_QH_QTD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.qtd_hw_seg[count].status = 0;
        g_XC_USBH_info.qtd_hw_seg[count].next = &g_XC_USBH_info.qtd_hw_seg[count+1];
    }
    g_XC_USBH_info.qtd_hw_seg[EHCI_QTD_QUEUE_ITEM_NUM-1].next = NULL;
    g_XC_USBH_info.qtd_pool.next = &g_XC_USBH_info.qtd_hw_seg[0];        


    //Inlitialize memory based structures
    g_XC_USBH_info.ohci_hcca_mem_paddr = /*0xC0000000 + */OHCI_HCCA_MEM_OFFSET;
    g_XC_USBH_info.ohci_hcca_mem_vaddr = g_XC_USBH_info.pmmfb + OHCI_HCCA_MEM_OFFSET;

    for(count = 0; count < OHCI_ED_QUEUE_ITEM_NUM; count++)
    {
        g_XC_USBH_info.ed_hw_seg[count].ohci_ed_hw_seg_paddr = /*0xC0000000 + */OHCI_ED_HW_SEG_MEM_OFFSET + OHCI_ED_TD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.ed_hw_seg[count].ohci_ed_hw_seg_vaddr = g_XC_USBH_info.pmmfb + OHCI_ED_HW_SEG_MEM_OFFSET + OHCI_ED_TD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.ed_hw_seg[count].status = 0;
        g_XC_USBH_info.ed_hw_seg[count].next = &g_XC_USBH_info.ed_hw_seg[count+1];
    }
    g_XC_USBH_info.ed_hw_seg[OHCI_ED_QUEUE_ITEM_NUM-1].next = NULL;
    g_XC_USBH_info.ed_pool.next = &g_XC_USBH_info.ed_hw_seg[0];

    for(count = 0; count < OHCI_TD_QUEUE_ITEM_NUM; count++)
    {
        g_XC_USBH_info.td_hw_seg[count].ohci_td_hw_seg_paddr = /*0xC0000000 + */OHCI_TD_HW_SEG_MEM_OFFSET + OHCI_ED_TD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.td_hw_seg[count].ohci_td_hw_seg_vaddr = g_XC_USBH_info.pmmfb + OHCI_TD_HW_SEG_MEM_OFFSET + OHCI_ED_TD_SEG_DEFAULT_LEN*count;
        g_XC_USBH_info.td_hw_seg[count].status = 0;
        g_XC_USBH_info.td_hw_seg[count].next = &g_XC_USBH_info.td_hw_seg[count+1];
    }
    g_XC_USBH_info.td_hw_seg[OHCI_TD_QUEUE_ITEM_NUM-1].next = NULL;
    g_XC_USBH_info.td_pool.next = &g_XC_USBH_info.td_hw_seg[0];        


    for(count = 0; count < USBH_DATA_BUF_SEG_NUM; count++)
    {
        g_XC_USBH_info.data_buf[count].data_buf_paddr = /*0xC0000000 + */USBH_DATA_BUF_OFFSET + USBH_DATA_BUF_SEG_SIZE*count;
        g_XC_USBH_info.data_buf[count].status = 0;
        g_XC_USBH_info.data_buf[count].next = &g_XC_USBH_info.data_buf[count+1];
    }
    g_XC_USBH_info.data_buf[USBH_DATA_BUF_SEG_NUM-1].next = NULL;
    g_XC_USBH_info.data_buf_pool.next = &g_XC_USBH_info.data_buf[0];        

#ifdef USBH_USE_INDIRECT_DMA
    g_XC_USBH_info.descriptor_offset = XC_USBH_INDIRECT_DMA_DESC_OFFSET;
    g_XC_USBH_info.desc_num = XC_USBH_INDIRECT_DMA_DESC_SIZE/sizeof(XC_DMADESCRIPTORS);
    g_XC_USBH_info.pdescriptor = g_XC_USBH_info.pmmfb + XC_USBH_INDIRECT_DMA_DESC_OFFSET;
#endif

    g_XC_USBH_info.dma_mask = (u64)0x80000000; //2G, shoudl be enough

    g_XC_USBH_Global_Struct_Initialized = 1;
    return 0;
}

EXPORT_SYMBOL(XC_USBH_Global_Struct_Init);

#endif
