/*********************************************************************
 *
 *  Copyright (C) 2004  Freescale Semiconductors, Inc.
 *
 ********************************************************************/
/*********************************************************************
 *  FILE: rio_boot.c
 *
 *  DESCRIPTION :
 *    Contains the function which will set up the host and the agent
 *     to let the agent boot from the host's FLASH device
 *    rio_boot : sets up the agent and host to permit booting over RapidIO
 *
 * NOTES :
 *    For fabric system, assumes fixed device allocation, i.e. device X
 *    is connected to port X-1
 * HISTORY
 * Version    Date     Auth.,Loc.     Comments
 *   0.1    27-Jul-04  LM and CC EKB  First released version
 *   0.2    14-Apr-05  LM, EKB        Updated for MPC8548 SRIO 
 ********************************************************************/

#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 immap_t *local_imm;
extern volatile ccsr_srio_t *local_srio;
extern volatile ccsr_local_ecm_t *local_ecm;
extern volatile srio_device_t *srio_device;
extern u32 system_type;
int cpu_en(int device_id);

/********************************************************************
int rio_boot(int device_id, u32 *trained)
This function sets up the host to redirect the agent reads to the FLASH,
sets up the registers in the agent which are required to enable it to
boot over RapidIO, and then starts the booting process.
********************************************************************/
int
rio_boot (int device_id)
{
  int i,boot;
    /******************************************************************
  double check that this device has been discovered 
  ******************************************************************/
  if(srio_device[device_id].imm == NULL)
  {
  	printf("ERROR : Parameters not initialised for device_id %d \n", device_id);
	return 1;
  }
  
  /*******************************************************************
  check if this device is configured to boot over RapidIO
  *******************************************************************/
  boot = srio_device[device_id].imm->im_gur.porbmsr;
  printf("srio_device[device_id].imm->im_gur.porbmsr = 0x%08x \n", boot); 
  if((boot & BOOT_LOCATION) == BOOT_LOCAL_FLASH)
  {
  	printf("This device is configured to boot from local FLASH \n");
    srio_device[device_id].ecm->eebpcr |= AGENT_BOOTING_EEBPCR;
	return cpu_en(device_id); 
  } else if ((boot & BOOT_LOCATION) != BOOT_OVER_RIO)
  {
  	printf("This device is not configured to boot over RapidIO \n");
	return SUCCESS;
	}
  /*******************************************************************
  set up the inbound window on the host to translate the incoming
  rio requests. The location of the agent boot image happens to be
  different for the point to point and fabric systems
  *******************************************************************/
  asm("sync"); 
  local_srio->riwbar2 = 0x00002000;
  local_srio->riwtar2 = 0x000ff000;
  local_srio->riwar2 = 0x80f50017;
  asm("sync");
  printf("Host : riwbar2 = 0x%08x, riwar2 = 0x%08x, riwtar2 = 0x%08x \n", local_srio->riwbar2,
  local_srio->riwar2, local_srio->riwtar2);
  

  /******************************************************************
  set up the outbound window on agent to direct rio request to deviceid 1 (boot proc)
  ******************************************************************/
  //srio_device[device_id].srio->rowtar0 = AGENT_BOOTING_ROWTAR; 
  srio_device[device_id].srio->rowbar6 = 0x000ff000;
  srio_device[device_id].srio->rowtar6 = 0x00002000;
  srio_device[device_id].srio->rowar6 = 0x80045017;
  printf("agent device rowbar6 = 0x%08x \n", srio_device[device_id].srio->rowbar6);
  printf("agent device rowar6 = 0x%08x \n", srio_device[device_id].srio->rowar6);
  printf("agent device rowtar6 = 0x%08x \n", srio_device[device_id].srio->rowtar6);
 
  /******************************************************************
  set up lawbar in agent to continue redirect boot ROM access to RIO interface,
  even after u-boot sets up the local definitions. Refer to documentation for more
  detail
  ******************************************************************/
  srio_device[device_id].ecm->lawbar0 = AGENT_BOOTING_LAWBAR;
  srio_device[device_id].ecm->lawar0 = AGENT_BOOTING_LAWAR;

  printf ("Before booting : \n");
  printf ("didcar= 0x%08x  \n", srio_device[device_id].srio->didcar);
  printf ("lcsbacsr = 0x%08x  \n", srio_device[device_id].srio->lcsbacsr);
  printf ("bdidcsr= 0x%08x  \n", srio_device[device_id].srio->bdidcsr);
  printf ("ccsrbar = 0x%08x \n", srio_device[device_id].ecm->ccsrbar);
  printf ("eebpcr = 0x%08x \n", srio_device[device_id].ecm->eebpcr);
  printf ("agent LAWBAR0 = 0x%08x \n", srio_device[device_id].ecm->lawbar0);
  printf ("agent LAWAR0  = 0x%08x \n", srio_device[device_id].ecm->lawar0);
  printf ("agent LAWBAR1 = 0x%08x \n", srio_device[device_id].ecm->lawbar1);
  printf ("agent LAWAR1  = 0x%08x \n", srio_device[device_id].ecm->lawar1);
  printf ("agent LAWBAR2 = 0x%08x \n", srio_device[device_id].ecm->lawbar2);
  printf ("agent LAWAR2  = 0x%08x \n", srio_device[device_id].ecm->lawar3);
  printf ("agent LAWBAR3 = 0x%08x \n", srio_device[device_id].ecm->lawbar3);
  printf ("agent LAWAR3  = 0x%08x \n", srio_device[device_id].ecm->lawar3);
  printf ("agent LAWBAR4 = 0x%08x \n", srio_device[device_id].ecm->lawbar4);
  printf ("agent LAWAR4  = 0x%08x \n", srio_device[device_id].ecm->lawar4);
  printf ("agent LAWBAR5 = 0x%08x \n", srio_device[device_id].ecm->lawbar5);
  printf ("agent LAWAR5  = 0x%08x \n", srio_device[device_id].ecm->lawar5);
  printf ("agent LAWBAR6 = 0x%08x \n", srio_device[device_id].ecm->lawbar6);
  printf ("agent LAWAR6  = 0x%08x \n", srio_device[device_id].ecm->lawar6);
  printf ("agent LAWBAR7 = 0x%08x \n", srio_device[device_id].ecm->lawbar7);
  printf ("agent LAWAR7  = 0x%08x \n", srio_device[device_id].ecm->lawar7);

  /*****************************************************************
  tell the agent it is permitted to generate RIO transactions
  *****************************************************************/
  srio_device[device_id].srio->pgccsr |= AGENT_BOOTING_PGCCSR;

  asm ("sync");
  return cpu_en(device_id);
}

int cpu_en(int device_id)
{
  /*****************************************************************
  enable the CPU and allow it to start booting
  *****************************************************************/
  srio_device[device_id].ecm->eebpcr |= AGENT_BOOTING_EEBPCR;

  printf ("Press any key to continue\n");

  /*****************************************************************
  this is in here as a wait for boot to complete!
  *****************************************************************/
  getc ();

  printf ("AFTER BOOT Read back data from device %d  through lcsbacsr \n",
          device_id);
  printf ("didcar= 0x%08x  \n", srio_device[device_id].srio->didcar);
  printf ("lcsbacsr = 0x%08x  \n", srio_device[device_id].srio->lcsbacsr);
  printf ("bdidcsr= 0x%08x  \n", srio_device[device_id].srio->bdidcsr);
  printf ("ccsrbar = 0x%08x \n", srio_device[device_id].ecm->ccsrbar);
  printf ("eebpcr = 0x%08x \n", srio_device[device_id].ecm->eebpcr);
  printf ("agent LAWBAR0 = 0x%08x \n", srio_device[device_id].ecm->lawbar0);
  printf ("agent LAWAR0  = 0x%08x \n", srio_device[device_id].ecm->lawar0);
  printf ("agent LAWBAR1 = 0x%08x \n", srio_device[device_id].ecm->lawbar1);
  printf ("agent LAWAR1  = 0x%08x \n", srio_device[device_id].ecm->lawar1);
  printf ("agent LAWBAR2 = 0x%08x \n", srio_device[device_id].ecm->lawbar2);
  printf ("agent LAWAR2  = 0x%08x \n", srio_device[device_id].ecm->lawar3);
  printf ("agent LAWBAR3 = 0x%08x \n", srio_device[device_id].ecm->lawbar3);
  printf ("agent LAWAR3  = 0x%08x \n", srio_device[device_id].ecm->lawar3);
  printf ("agent LAWBAR4 = 0x%08x \n", srio_device[device_id].ecm->lawbar4);
  printf ("agent LAWAR4  = 0x%08x \n", srio_device[device_id].ecm->lawar4);
  printf ("agent LAWBAR5 = 0x%08x \n", srio_device[device_id].ecm->lawbar5);
  printf ("agent LAWAR5  = 0x%08x \n", srio_device[device_id].ecm->lawar5);
  printf ("agent LAWBAR6 = 0x%08x \n", srio_device[device_id].ecm->lawbar6);
  printf ("agent LAWAR6  = 0x%08x \n", srio_device[device_id].ecm->lawar6);
  printf ("agent LAWBAR7 = 0x%08x \n", srio_device[device_id].ecm->lawbar7);
  printf ("agent LAWAR7  = 0x%08x \n", srio_device[device_id].ecm->lawar7);
  
  srio_device[device_id].booted = 1;

  return SUCCESS;
}

