/*********************************************************************
 *
 *  Copyright (C) 2005  Freescale Semiconductors, Inc.
 *
 ********************************************************************/
/*********************************************************************
 *  FILE: rio_setup.c
 *
 *  DESCRIPTION :
 *    Contains a number of functions used to set up the local and
 *    remote processors for RapidIO transactions
 *    setup_remote_lcs_access : sets up an outbound window on the
 *     local processor and the inbound window on one agent, to permit
 *     access to the CCSR area of that agent
 *    enable_rio_mem_access : sets up the host and the agent for the host's
 *     access to the agent's memory.
 *    local_setup_inbound_window : sets up an inbound window on the host to
 *     permit the agents to access the hosts memory
 *
 *
 * NOTES :
 *
 *
 * HISTORY
 * Version    Date     Auth.,Loc.     Comments
 *   0.1    27-Jul-04   LM, EKB       First released version
 *   0.2    19-Apr-05   LM, EKB       Updated fro SRIO on MPC8548
 ********************************************************************/

#include <common.h>
#include <syscall.h>
#include <asm-ppc/immap_85xx.h>
#include <asm-ppc/mmu.h>

//#include "rio_regs.h"
#include "rio_bringup.h"


extern volatile srio_device_t *srio_device;
extern volatile ccsr_srio_t *local_srio;
extern u32 nextdevid;


/********************************************************************
int setup_remote_lcs_access(u32 deviceid)
Sets up an OB window on the host and an IB LCS window on one of the
agents to permit the host to access that agents CCSR area.

*********************************************************************/
int
setup_remote_lcs_access (u32 deviceid)
{
	u32 temp; 

  /*********************************************************************
  set up the base addres of the IB window on the agent
  *********************************************************************/
  MAINT_WRITE (deviceid, 0xFF, RIO_LCSBACSR_OFFSET,
               CCSR_ADDR_ON_RIO >> SHIFT_RIO_ADDR_TO_LCSBACSR);
  printf("write 0x%08x to LCSBAR of processor %d. \n",(CCSR_ADDR_ON_RIO >> SHIFT_RIO_ADDR_TO_LCSBACSR), deviceid ); 	       

  /*********************************************************************
  then set up the mapping to that space. Base + 1MBytes per deviceID
  **********************************************************************/
  srio_device[deviceid].imm = (immap_t *) (LCS_BASE + (deviceid * MBYTE));
  srio_device[deviceid].srio = (ccsr_srio_t *)(((char*)srio_device[deviceid].imm) + 0xC0000);
  srio_device[deviceid].ecm = &(srio_device[deviceid].imm->im_local_ecm);
  
  printf("Initialise pointers to the registers, accessed through LCS \n"); 
  printf("srio_device[%d].imm = 0x%08x \n", deviceid, srio_device[deviceid].imm);
  printf("srio_device[%d].srio = 0x%08x \n", deviceid, srio_device[deviceid].srio);
  printf("srio_device[%d].ecm = 0x%08x \n", deviceid, srio_device[deviceid].ecm);

//  printf ("rowbar2 = 0x%08x, rowar2 = 0x%08x, rowtar2 = 0x%08x\n",
 //         local_srio->rowbar2, local_srio->rowar2, local_srio->rowtar2);
 // printf ("rowbar4 = 0x%08x, rowar4 = 0x%08x, rowtar4 = 0x%08x\n",
 //         local_srio->rowbar4, local_srio->rowar4, local_srio->rowtar4);
	  
//	  	printf("local_srio->rows1r2 = 0x%08x @ address 0x%08x \n",local_srio->rows1r2, &local_srio->rows1r2); 
//	printf("local_srio->rows2r2 = 0x%08x @ address 0x%08x \n",local_srio->rows2r2, &local_srio->rows2r2); 
//	printf("local_srio->rows3r2 = 0x%08x @ address 0x%08x \n",local_srio->rows3r2, &local_srio->rows3r2); 


  
     
    /*********************************************************************
    read back recognisable data to demonstrate that this has been set up
    correctly
    *********************************************************************/
     MAINT_READ (deviceid, 0xFF, RIO_BDIDCSR_OFFSET, temp);

    if(temp != 	srio_device[deviceid].srio->bdidcsr)
    {
  	printf("lcs does not seem to be set up correctly!!!\n"); 
	printf("maint read of bdid = 0x%08x, LCS read = 0x%08x \n",temp, srio_device[deviceid].srio->bdidcsr);  
	return 1; 
    }
    else
    {
    	printf("Confirmed correct operation of LCS by comparing to maintenance read \n"); 
    }



 


  return SUCCESS;
}

/********************************************************************
int enable_rio_mem_access(uint device_id, u32 *trained)
Sets up the OB window on the host and the IB window on the agent
to permit the host to access the agent's memory
*********************************************************************/
int
enable_rio_mem_access (uint device_id)
{
  
  /********************************************************************
  check that the device has been booted 
  ********************************************************************/
  if(srio_device[device_id].booted != 1)
  {
  	printf("Cannot set up mem access to device %d \n", device_id);
	printf("it has not been booted \n");
  }
 
  /*********************************************************************
  set up an outgoing window which will permit access to the local memory
  of the agent device
  *********************************************************************/
  srio_device[device_id].mem_block = (u32 *)(REMOTEMEMBASE + (device_id * MBYTE * 4));
  /**********************************************************************
  also set up in inbound window on the agent to accept these transactions
  and redirect them to 'safe' area of DDR
  **********************************************************************/
  srio_device[device_id].srio->riwbar1 = 0;
  srio_device[device_id].srio->riwtar1 = AGENT_RIWTAR_DEFAULTS;
  srio_device[device_id].srio->riwar1 = AGENT_RIWAR_DEFAULTS;
  
  printf ("Set up IB window on agent to permit host to access its memory \n");
  printf("AGENT_RIWTAR_DEFAULTS = 0x%08x \n", AGENT_RIWTAR_DEFAULTS); 
  asm("sync"); 
  printf ("Agent riwbar1=0x%08x, riwtar1=0x%08x, riwar1=0x%08x\n",
          srio_device[device_id].srio->riwbar1, srio_device[device_id].srio->riwtar1,
          srio_device[device_id].srio->riwar1);
	  printf("&srio_device[%d].srio->riwbar1 = 0x%08x \n", device_id, &srio_device[device_id].srio->riwbar1); 
	   printf("&srio_device[%d].srio->riwtar1 = 0x%08x \n", device_id, &srio_device[device_id].srio->riwtar1); 
	  

  
  return SUCCESS;
}

/********************************************************************
Sets up the inbound window on the local processor to accept incoming
RapidIO transactions
********************************************************************/
void
local_setup_inbound_window (void)
{
  local_srio->riwbar1 = 0;
  local_srio->riwtar1 = HOST_RIWTAR_DEFAULTS;
  local_srio->riwar1 = HOST_RIWAR_DEFAULTS;
  printf
    ("Set up inbound window on host to re-direct incoming rio to 'safe' area \n");
  printf ("riwbar1 = 0x%08x, riwar1 = 0x%08x, riwtar1 = 0x%08x\n",
          local_srio->riwbar1, local_srio->riwar1, local_srio->riwtar1);
}
