uboot/board/renesas/ap325rxa/cpld-ap325rxa.c
<<
>>
Prefs
   1/***************************************************************
   2 * Project:
   3 *        CPLD SlaveSerial Configuration via embedded microprocessor.
   4 *
   5 * Copyright info:
   6 *
   7 *        This is free software; you can redistribute it and/or modify
   8 *        it as you like.
   9 *
  10 *        This program is distributed in the hope that it will be useful,
  11 *        but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13 *
  14 * Description:
  15 *
  16 *      This is the main source file that will allow a microprocessor
  17 *      to configure Xilinx Virtex, Virtex-E, Virtex-EM, Virtex-II,
  18 *      and Spartan-II devices via the SlaveSerial Configuration Mode.
  19 *      This code is discussed in Xilinx Application Note, XAPP502.
  20 *
  21 * History:
  22 *        3-October-2001  MN/MP  - Created
  23 *        20-August-2008  Renesas Solutions - Modified to SH7723
  24 ****************************************************************/
  25
  26#include <common.h>
  27
  28/* Serial */
  29#define SCIF_BASE 0xffe00000 /* SCIF0 */
  30#define SCSMR   (vu_short *)(SCIF_BASE + 0x00)
  31#define SCBRR   (vu_char *)(SCIF_BASE + 0x04)
  32#define SCSCR   (vu_short *)(SCIF_BASE + 0x08)
  33#define SC_TDR  (vu_char *)(SCIF_BASE + 0x0C)
  34#define SC_SR   (vu_short *)(SCIF_BASE + 0x10)
  35#define SCFCR   (vu_short *)(SCIF_BASE + 0x18)
  36#define RFCR    (vu_long *)0xFE400020
  37
  38#define SCSCR_INIT              0x0038
  39#define SCSCR_CLR               0x0000
  40#define SCFCR_INIT              0x0006
  41#define SCSMR_INIT              0x0080
  42#define RFCR_CLR                0xA400
  43#define SCI_TD_E                0x0020
  44#define SCI_TDRE_CLEAR  0x00df
  45
  46#define BPS_SETTING_VALUE       1 /* 12.5MHz */
  47#define WAIT_RFCR_COUNTER       500
  48
  49/* CPLD data size */
  50#define CPLD_DATA_SIZE  169216
  51
  52/* out */
  53#define CPLD_PFC_ADR    ((vu_short *)0xA4050112)
  54
  55#define CPLD_PROG_ADR   ((vu_char *)0xA4050132)
  56#define CPLD_PROG_DAT   0x80
  57
  58/* in */
  59#define CPLD_INIT_ADR   ((vu_char *)0xA4050132)
  60#define CPLD_INIT_DAT   0x40
  61#define CPLD_DONE_ADR   ((vu_char *)0xA4050132)
  62#define CPLD_DONE_DAT   0x20
  63
  64#define HIZCRB                  ((vu_short *)0xA405015A)
  65
  66/* data */
  67#define CPLD_NOMAL_START        0xA0A80000
  68#define CPLD_SAFE_START         0xA0AC0000
  69#define MODE_SW                         (vu_char *)0xA405012A
  70
  71static void init_cpld_loader(void)
  72{
  73
  74        *SCSCR = SCSCR_CLR;
  75        *SCFCR = SCFCR_INIT;
  76        *SCSMR = SCSMR_INIT;
  77
  78        *SCBRR = BPS_SETTING_VALUE;
  79
  80        *RFCR = RFCR_CLR; /* Refresh counter clear */
  81
  82        while (*RFCR < WAIT_RFCR_COUNTER)
  83                ;
  84
  85        *SCFCR = 0x0; /* RTRG=00, TTRG=00 */
  86                                  /* MCE=0,TFRST=0,RFRST=0,LOOP=0 */
  87        *SCSCR = SCSCR_INIT;
  88}
  89
  90static int check_write_ready(void)
  91{
  92        u16 status = *SC_SR;
  93        return status & SCI_TD_E;
  94}
  95
  96static void write_cpld_data(char ch)
  97{
  98        while (!check_write_ready())
  99                ;
 100
 101        *SC_TDR = ch;
 102        *SC_SR;
 103        *SC_SR = SCI_TDRE_CLEAR;
 104}
 105
 106static int delay(void)
 107{
 108        int i;
 109        int c = 0;
 110        for (i = 0; i < 200; i++) {
 111                c = *(volatile int *)0xa0000000;
 112        }
 113        return c;
 114}
 115
 116/***********************************************************************
 117 *
 118 * Function:     slave_serial
 119 *
 120 * Description:  Initiates SlaveSerial Configuration.
 121 *               Calls ShiftDataOut() to output serial data
 122 *
 123 ***********************************************************************/
 124static void slave_serial(void)
 125{
 126        int i;
 127        unsigned char *flash;
 128
 129        *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */
 130        delay();
 131
 132        /*
 133         * Toggle Program Pin by Toggling Program_OE bit
 134         * This is accomplished by writing to the Program Register in the CPLD
 135         *
 136         * NOTE: The Program_OE bit should be driven high to bring the Virtex
 137         *      Program Pin low. Likewise, it should be driven low
 138         *      to bring the Virtex Program Pin to High-Z
 139         */
 140
 141        *CPLD_PROG_ADR &= ~CPLD_PROG_DAT; /* PROGRAM_OE LOW */
 142        delay();
 143
 144        /*
 145         * Bring Program High-Z
 146         * (Drive Program_OE bit low to bring Virtex Program Pin to High-Z
 147         */
 148
 149        /* Program_OE bit Low brings the Virtex Program Pin to High Z: */
 150        *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */
 151
 152        while ((*CPLD_INIT_ADR & CPLD_INIT_DAT) == 0)
 153                delay();
 154
 155        /* Begin Slave-Serial Configuration */
 156        flash = (unsigned char *)CPLD_NOMAL_START;
 157
 158        for (i = 0; i < CPLD_DATA_SIZE; i++)
 159                write_cpld_data(*flash++);
 160}
 161
 162/***********************************************************************
 163 *
 164 * Function: check_done_bit
 165 *
 166 * Description: This function takes monitors the CPLD Input Register
 167 *                 by checking the status of the DONE bit in that Register.
 168 *               By doing so, it monitors the Xilinx Virtex device's DONE
 169 *               Pin to see if configuration bitstream has been properly
 170 *               loaded
 171 *
 172 ***********************************************************************/
 173static void check_done_bit(void)
 174{
 175        while (!(*CPLD_DONE_ADR & CPLD_DONE_DAT))
 176                ;
 177}
 178
 179/***********************************************************************
 180 *
 181 * Function: init_cpld
 182 *
 183 * Description: Begins Slave Serial configuration of Xilinx FPGA
 184 *
 185 ***********************************************************************/
 186void init_cpld(void)
 187{
 188        /* Init serial device */
 189        init_cpld_loader();
 190
 191        if (*CPLD_DONE_ADR & CPLD_DONE_DAT)     /* Already DONE */
 192                return;
 193
 194        *HIZCRB = 0x0000;
 195        *CPLD_PFC_ADR = 0x7c00;                 /* FPGA PROG = OUTPUT */
 196
 197        /* write CPLD data from NOR flash to device */
 198        slave_serial();
 199
 200        /*
 201         * Monitor the DONE bit in the CPLD Input Register to see if
 202         * configuration successful
 203         */
 204
 205        check_done_bit();
 206}
 207