//
// 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/AT91SAM9260.h>

#define AT91C_SDRAM (*(volatile unsigned int *)0x20000000)

void 
init_sdram_pll(void)
{
  volatile unsigned i;

#ifdef __FLASH_BUILD
  // Set flash for an EMBEST SAM9260V1 board
  SMC_SETUP0 = 0x00010001;
  SMC_PULSE0 = 0x0a090706;
  SMC_CYCLE0 = 0x000a0007;
  SMC_MODE0 =  0x00001103;

  CKGR_MOR = 0x801;
  while (!(CKGR_MCFR & CKGR_MCFR_MAINRDY));
  PMC_MCKR = 1;
#endif

  CKGR_PLLAR = 0x20603F09; // MULA=97, DIVA=9 - 18.432*97/9 = 198.656

  while (!(PMC_SR & PMC_SR_LOCKA));

  // Use PLL A as processor clock and master clock divided by 2
  PMC_MCKR = 0x00000102;
  while (!(PMC_SR & PMC_SR_MCKRDY));

  // 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 = (1<<SDRAMC_CR_NC_BIT) | // 9 Column Bits
              (2<<SDRAMC_CR_NR_BIT) | // 13 Row Bits
              (1<<SDRAMC_CR_NB_BIT) | // 4 Banks
              (2<<SDRAMC_CR_CAS_BIT) | // CAS 2
              (0<<SDRAMC_CR_DBW_BIT) | // 32 bit data bus
              (2<<SDRAMC_CR_TWR_BIT) | 
              (7<<SDRAMC_CR_TRC_BIT) |
              (2<<SDRAMC_CR_TRP_BIT) |
              (2<<SDRAMC_CR_TRCD_BIT) |
              (5<<SDRAMC_CR_TRAS_BIT) |
              (8<<SDRAMC_CR_TXSR_BIT);
  
  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
  MATRIX_MRCR = 0x3;
#endif
}


