//
// Copyright (c) 2009 Rowley Associates Limited.
//
// This file may be distributed under the terms of the License Agreement
// provided with this software.
//
// THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// The SDRAM init code was copied from the ATMEL Application Note
//   "Using SDRAM on AT91SAM9 Microcontrollers"
//

#include <targets/AT91RM9200.h>
#define EBI_CSA_EBI_CS1A EBI_CSA_CS1A

#define AT91C_SDRAM (*(volatile unsigned int *)0x20000000)

void 
init_sdram_pll(void)
{
  volatile unsigned i=0; 

#ifdef __FLASH_BUILD
  while (!(CKGR_MCFR & CKGR_MCFR_MAINRDY) && (i++<100));

  // Set flash wait states
  SMC_CSR0 = (0x7f & 0x4)|(1<<7)|((0xf<<8)&0x200)|(1<<12)|(1<<13);

  CKGR_MOR = 0x801;
  i = 0;
  while (!(CKGR_MCFR & CKGR_MCFR_MAINRDY) && (i++<100));  
#endif

  // Set up PLL A
  CKGR_PLLAR = 0x20263E04; // MULA=39, DIVA=4 - 18.432/4*39 = 179.712
  i = 0;
  while (!(PMC_SR & PMC_SR_LOCKA) && (i++<100));

  PMC_MCKR = 0x00000202;
  i = 0;
  while (!(PMC_SR & PMC_SR_MCKRDY) && (i++<100));

  // select 32 bit data bus
  PIOC_PDR = 0xFFFF0000; 
  PIOC_ASR = 0xFFFF0000;

  // assign EBI CSA1 to SDRAM
  EBI_CSA |= EBI_CSA_EBI_CS1A;
  
  // SDRAM timings and configuration
  SDRAMC_CR = 0x7fffffd0;
  
  for (i =0; i< 1000;i++);
  
  // "All Banks Precharge"
  SDRAMC_MR = 2;
  AT91C_SDRAM = 0;          

  for (i =0; i< 1000; i++);

  // 8 "Auto Refresh Commands"
  for (i=0;i<8;i++)
    {
      SDRAMC_MR = 4;
      AT91C_SDRAM = 0;
    }
  // "Load Mode Register"
  SDRAMC_MR = 3;
  AT91C_SDRAM = 0;  
  // Set Refresh Rate to 7.8 us
  SDRAMC_TR = 780;
  // Switch to normal mode
  SDRAMC_MR = 0;
  AT91C_SDRAM = 0;

#ifdef __FLASH_BUILD
  // map SRAM to address zero
  MC_RCR = 0x1;
#endif
}


