uboot/board/bf537-stamp/post-memory.c
<<
>>
Prefs
   1#include <common.h>
   2#include <asm/io.h>
   3
   4#include <post.h>
   5#include <watchdog.h>
   6
   7#if CONFIG_POST & CONFIG_SYS_POST_MEMORY
   8#define CLKIN 25000000
   9#define PATTERN1 0x5A5A5A5A
  10#define PATTERN2 0xAAAAAAAA
  11
  12#define CCLK_NUM        4
  13#define SCLK_NUM        3
  14
  15void post_out_buff(char *buff);
  16int post_key_pressed(void);
  17void post_init_pll(int mult, int div);
  18int post_init_sdram(int sclk);
  19void post_init_uart(int sclk);
  20
  21const int pll[CCLK_NUM][SCLK_NUM][2] = {
  22        { {20, 4}, {20, 5}, {20, 10} }, /* CCLK = 500M */
  23        { {16, 4}, {16, 5}, {16, 8} },  /* CCLK = 400M */
  24        { {8, 2}, {8, 4}, {8, 5} },     /* CCLK = 200M */
  25        { {4, 1}, {4, 2}, {4, 4} }      /* CCLK = 100M */
  26};
  27const char *const log[CCLK_NUM][SCLK_NUM] = {
  28        {"CCLK-500MHz SCLK-125MHz:    Writing...\0",
  29         "CCLK-500MHz SCLK-100MHz:    Writing...\0",
  30         "CCLK-500MHz SCLK- 50MHz:    Writing...\0",},
  31        {"CCLK-400MHz SCLK-100MHz:    Writing...\0",
  32         "CCLK-400MHz SCLK- 80MHz:    Writing...\0",
  33         "CCLK-400MHz SCLK- 50MHz:    Writing...\0",},
  34        {"CCLK-200MHz SCLK-100MHz:    Writing...\0",
  35         "CCLK-200MHz SCLK- 50MHz:    Writing...\0",
  36         "CCLK-200MHz SCLK- 40MHz:    Writing...\0",},
  37        {"CCLK-100MHz SCLK-100MHz:    Writing...\0",
  38         "CCLK-100MHz SCLK- 50MHz:    Writing...\0",
  39         "CCLK-100MHz SCLK- 25MHz:    Writing...\0",},
  40};
  41
  42int memory_post_test(int flags)
  43{
  44        int addr;
  45        int m, n;
  46        int sclk, sclk_temp;
  47        int ret = 1;
  48
  49        sclk_temp = CLKIN / 1000000;
  50        sclk_temp = sclk_temp * CONFIG_VCO_MULT;
  51        for (sclk = 0; sclk_temp > 0; sclk++)
  52                sclk_temp -= CONFIG_SCLK_DIV;
  53        sclk = sclk * 1000000;
  54        post_init_uart(sclk);
  55        if (post_key_pressed() == 0)
  56                return 0;
  57
  58        for (m = 0; m < CCLK_NUM; m++) {
  59                for (n = 0; n < SCLK_NUM; n++) {
  60                        /* Calculate the sclk */
  61                        sclk_temp = CLKIN / 1000000;
  62                        sclk_temp = sclk_temp * pll[m][n][0];
  63                        for (sclk = 0; sclk_temp > 0; sclk++)
  64                                sclk_temp -= pll[m][n][1];
  65                        sclk = sclk * 1000000;
  66
  67                        post_init_pll(pll[m][n][0], pll[m][n][1]);
  68                        post_init_sdram(sclk);
  69                        post_init_uart(sclk);
  70                        post_out_buff("\n\r\0");
  71                        post_out_buff(log[m][n]);
  72                        for (addr = 0x0; addr < CONFIG_SYS_MAX_RAM_SIZE; addr += 4)
  73                                *(unsigned long *)addr = PATTERN1;
  74                        post_out_buff("Reading...\0");
  75                        for (addr = 0x0; addr < CONFIG_SYS_MAX_RAM_SIZE; addr += 4) {
  76                                if ((*(unsigned long *)addr) != PATTERN1) {
  77                                        post_out_buff("Error\n\r\0");
  78                                        ret = 0;
  79                                }
  80                        }
  81                        post_out_buff("OK\n\r\0");
  82                }
  83        }
  84        if (ret)
  85                post_out_buff("memory POST passed\n\r\0");
  86        else
  87                post_out_buff("memory POST failed\n\r\0");
  88
  89        post_out_buff("\n\r\n\r\0");
  90        return 1;
  91}
  92
  93void post_init_uart(int sclk)
  94{
  95        int divisor;
  96
  97        for (divisor = 0; sclk > 0; divisor++)
  98                sclk -= 57600 * 16;
  99
 100        *pPORTF_FER = 0x000F;
 101        *pPORTH_FER = 0xFFFF;
 102
 103        *pUART_GCTL = 0x00;
 104        *pUART_LCR = 0x83;
 105        SSYNC();
 106        *pUART_DLL = (divisor & 0xFF);
 107        SSYNC();
 108        *pUART_DLH = ((divisor >> 8) & 0xFF);
 109        SSYNC();
 110        *pUART_LCR = 0x03;
 111        SSYNC();
 112        *pUART_GCTL = 0x01;
 113        SSYNC();
 114}
 115
 116void post_out_buff(char *buff)
 117{
 118
 119        int i = 0;
 120        for (i = 0; i < 0x80000; i++)
 121                ;
 122        i = 0;
 123        while ((buff[i] != '\0') && (i != 100)) {
 124                while (!(*pUART_LSR & 0x20)) ;
 125                *pUART_THR = buff[i];
 126                SSYNC();
 127                i++;
 128        }
 129        for (i = 0; i < 0x80000; i++)
 130                ;
 131}
 132
 133/* Using sw10-PF5 as the hotkey */
 134#define KEY_LOOP 0x80000
 135#define KEY_DELAY 0x80
 136int post_key_pressed(void)
 137{
 138        int i, n;
 139        unsigned short value;
 140
 141        *pPORTF_FER &= ~PF5;
 142        *pPORTFIO_DIR &= ~PF5;
 143        *pPORTFIO_INEN |= PF5;
 144        SSYNC();
 145
 146        post_out_buff("########Press SW10 to enter Memory POST########: 3\0");
 147        for (i = 0; i < KEY_LOOP; i++) {
 148                value = *pPORTFIO & PF5;
 149                if (*pUART0_RBR == 0x0D) {
 150                        value = 0;
 151                        goto key_pressed;
 152                }
 153                if (value != 0)
 154                        goto key_pressed;
 155                for (n = 0; n < KEY_DELAY; n++)
 156                        asm("nop");
 157        }
 158        post_out_buff("\b2\0");
 159
 160        for (i = 0; i < KEY_LOOP; i++) {
 161                value = *pPORTFIO & PF5;
 162                if (*pUART0_RBR == 0x0D) {
 163                        value = 0;
 164                        goto key_pressed;
 165                }
 166                if (value != 0)
 167                        goto key_pressed;
 168                for (n = 0; n < KEY_DELAY; n++)
 169                        asm("nop");
 170        }
 171        post_out_buff("\b1\0");
 172
 173        for (i = 0; i < KEY_LOOP; i++) {
 174                value = *pPORTFIO & PF5;
 175                if (*pUART0_RBR == 0x0D) {
 176                        value = 0;
 177                        goto key_pressed;
 178                }
 179                if (value != 0)
 180                        goto key_pressed;
 181                for (n = 0; n < KEY_DELAY; n++)
 182                        asm("nop");
 183        }
 184      key_pressed:
 185        post_out_buff("\b0");
 186        post_out_buff("\n\r\0");
 187        if (value == 0)
 188                return 0;
 189        post_out_buff("Hotkey has been pressed, Enter POST . . . . . .\n\r\0");
 190        return 1;
 191}
 192
 193void post_init_pll(int mult, int div)
 194{
 195
 196        *pSIC_IWR = 0x01;
 197        *pPLL_CTL = (mult << 9);
 198        *pPLL_DIV = div;
 199        asm("CLI R2;");
 200        asm("IDLE;");
 201        asm("STI R2;");
 202        while (!(*pPLL_STAT & 0x20)) ;
 203}
 204
 205int post_init_sdram(int sclk)
 206{
 207        int SDRAM_tRP, SDRAM_tRP_num, SDRAM_tRAS, SDRAM_tRAS_num, SDRAM_tRCD,
 208            SDRAM_tWR;
 209        int SDRAM_Tref, SDRAM_NRA, SDRAM_CL, SDRAM_SIZE, SDRAM_WIDTH,
 210            mem_SDGCTL, mem_SDBCTL, mem_SDRRC;
 211
 212        if ((sclk > 119402985)) {
 213                SDRAM_tRP = TRP_2;
 214                SDRAM_tRP_num = 2;
 215                SDRAM_tRAS = TRAS_7;
 216                SDRAM_tRAS_num = 7;
 217                SDRAM_tRCD = TRCD_2;
 218                SDRAM_tWR = TWR_2;
 219        } else if ((sclk > 104477612) && (sclk <= 119402985)) {
 220                SDRAM_tRP = TRP_2;
 221                SDRAM_tRP_num = 2;
 222                SDRAM_tRAS = TRAS_6;
 223                SDRAM_tRAS_num = 6;
 224                SDRAM_tRCD = TRCD_2;
 225                SDRAM_tWR = TWR_2;
 226        } else if ((sclk > 89552239) && (sclk <= 104477612)) {
 227                SDRAM_tRP = TRP_2;
 228                SDRAM_tRP_num = 2;
 229                SDRAM_tRAS = TRAS_5;
 230                SDRAM_tRAS_num = 5;
 231                SDRAM_tRCD = TRCD_2;
 232                SDRAM_tWR = TWR_2;
 233        } else if ((sclk > 74626866) && (sclk <= 89552239)) {
 234                SDRAM_tRP = TRP_2;
 235                SDRAM_tRP_num = 2;
 236                SDRAM_tRAS = TRAS_4;
 237                SDRAM_tRAS_num = 4;
 238                SDRAM_tRCD = TRCD_2;
 239                SDRAM_tWR = TWR_2;
 240        } else if ((sclk > 66666667) && (sclk <= 74626866)) {
 241                SDRAM_tRP = TRP_2;
 242                SDRAM_tRP_num = 2;
 243                SDRAM_tRAS = TRAS_3;
 244                SDRAM_tRAS_num = 3;
 245                SDRAM_tRCD = TRCD_2;
 246                SDRAM_tWR = TWR_2;
 247        } else if ((sclk > 59701493) && (sclk <= 66666667)) {
 248                SDRAM_tRP = TRP_1;
 249                SDRAM_tRP_num = 1;
 250                SDRAM_tRAS = TRAS_4;
 251                SDRAM_tRAS_num = 4;
 252                SDRAM_tRCD = TRCD_1;
 253                SDRAM_tWR = TWR_2;
 254        } else if ((sclk > 44776119) && (sclk <= 59701493)) {
 255                SDRAM_tRP = TRP_1;
 256                SDRAM_tRP_num = 1;
 257                SDRAM_tRAS = TRAS_3;
 258                SDRAM_tRAS_num = 3;
 259                SDRAM_tRCD = TRCD_1;
 260                SDRAM_tWR = TWR_2;
 261        } else if ((sclk > 29850746) && (sclk <= 44776119)) {
 262                SDRAM_tRP = TRP_1;
 263                SDRAM_tRP_num = 1;
 264                SDRAM_tRAS = TRAS_2;
 265                SDRAM_tRAS_num = 2;
 266                SDRAM_tRCD = TRCD_1;
 267                SDRAM_tWR = TWR_2;
 268        } else if (sclk <= 29850746) {
 269                SDRAM_tRP = TRP_1;
 270                SDRAM_tRP_num = 1;
 271                SDRAM_tRAS = TRAS_1;
 272                SDRAM_tRAS_num = 1;
 273                SDRAM_tRCD = TRCD_1;
 274                SDRAM_tWR = TWR_2;
 275        } else {
 276                SDRAM_tRP = TRP_1;
 277                SDRAM_tRP_num = 1;
 278                SDRAM_tRAS = TRAS_1;
 279                SDRAM_tRAS_num = 1;
 280                SDRAM_tRCD = TRCD_1;
 281                SDRAM_tWR = TWR_2;
 282        }
 283        /*SDRAM INFORMATION: */
 284        SDRAM_Tref = 64;        /* Refresh period in milliseconds */
 285        SDRAM_NRA = 4096;       /* Number of row addresses in SDRAM */
 286        SDRAM_CL = CL_3;        /* 2 */
 287
 288        SDRAM_SIZE = EBSZ_64;
 289        SDRAM_WIDTH = EBCAW_10;
 290
 291        mem_SDBCTL = SDRAM_WIDTH | SDRAM_SIZE | EBE;
 292
 293        /* Equation from section 17 (p17-46) of BF533 HRM */
 294        mem_SDRRC =
 295            (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) -
 296            (SDRAM_tRAS_num + SDRAM_tRP_num);
 297
 298        /* Enable SCLK Out */
 299        mem_SDGCTL =
 300            (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR
 301             | PSS);
 302
 303        SSYNC();
 304
 305        *pEBIU_SDGCTL |= 0x1000000;
 306        /* Set the SDRAM Refresh Rate control register based on SSCLK value */
 307        *pEBIU_SDRRC = mem_SDRRC;
 308
 309        /* SDRAM Memory Bank Control Register */
 310        *pEBIU_SDBCTL = mem_SDBCTL;
 311
 312        /* SDRAM Memory Global Control Register */
 313        *pEBIU_SDGCTL = mem_SDGCTL;
 314        SSYNC();
 315        return mem_SDRRC;
 316}
 317
 318#endif                          /* CONFIG_POST & CONFIG_SYS_POST_MEMORY */
 319