uboot/cpu/i386/sc520/sc520.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/* stuff specific for the sc520,
  25 * but idependent of implementation */
  26
  27#include <common.h>
  28#include <asm/io.h>
  29#include <asm/ic/sc520.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33/*
  34 * utility functions for boards based on the AMD sc520
  35 *
  36 * void init_sc520(void)
  37 * unsigned long init_sc520_dram(void)
  38 */
  39
  40volatile sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)0xfffef000;
  41
  42void init_sc520(void)
  43{
  44        /* Set the UARTxCTL register at it's slower,
  45         * baud clock giving us a 1.8432 MHz reference
  46         */
  47        sc520_mmcr->uart1ctl = 0x07;
  48        sc520_mmcr->uart2ctl = 0x07;
  49
  50        /* first set the timer pin mapping */
  51        sc520_mmcr->clksel = 0x72;      /* no clock frequency selected, use 1.1892MHz */
  52
  53        /* enable PCI bus arbitrer */
  54        sc520_mmcr->sysarbctl = 0x02;   /* enable concurrent mode */
  55
  56        sc520_mmcr->sysarbmenb = 0x1f;  /* enable external grants */
  57        sc520_mmcr->hbctl = 0x04;       /* enable posted-writes */
  58
  59        if (CONFIG_SYS_SC520_HIGH_SPEED) {
  60                sc520_mmcr->cpuctl = 0x02;      /* set it to 133 MHz and write back */
  61                gd->cpu_clk = 133000000;
  62                printf("## CPU Speed set to 133MHz\n");
  63        } else {
  64                sc520_mmcr->cpuctl = 0x01;      /* set it to 100 MHz and write back */
  65                printf("## CPU Speed set to 100MHz\n");
  66                gd->cpu_clk = 100000000;
  67        }
  68
  69
  70        /* wait at least one millisecond */
  71        asm("movl       $0x2000,%%ecx\n"
  72            "0:         pushl %%ecx\n"
  73            "popl       %%ecx\n"
  74            "loop 0b\n": : : "ecx");
  75
  76        /* turn on the SDRAM write buffer */
  77        sc520_mmcr->dbctl = 0x11;
  78
  79        /* turn on the cache and disable write through */
  80        asm("movl       %%cr0, %%eax\n"
  81            "andl       $0x9fffffff, %%eax\n"
  82            "movl       %%eax, %%cr0\n"  : : : "eax");
  83}
  84
  85unsigned long init_sc520_dram(void)
  86{
  87        bd_t *bd = gd->bd;
  88
  89        u32 dram_present=0;
  90        u32 dram_ctrl;
  91#ifdef CONFIG_SYS_SDRAM_DRCTMCTL
  92        /* these memory control registers are set up in the assember part,
  93         * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
  94         * after we are running a stack in RAM, we have troubles.  Besides,
  95         * these refresh and delay values are better ? simply specified
  96         * outright in the include/configs/{cfg} file since the HW designer
  97         * simply dictates it.
  98         */
  99#else
 100        int val;
 101
 102        int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
 103        int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
 104        int ras_cas_delay       = CONFIG_SYS_SDRAM_RAS_CAS_DELAY;
 105
 106        /* set SDRAM speed here */
 107
 108        refresh_rate/=78;
 109        if (refresh_rate<=1) {
 110                val = 0;  /* 7.8us */
 111        } else if (refresh_rate==2) {
 112                val = 1;  /* 15.6us */
 113        } else if (refresh_rate==3 || refresh_rate==4) {
 114                val = 2;  /* 31.2us */
 115        } else {
 116                val = 3;  /* 62.4us */
 117        }
 118
 119        sc520_mmcr->drcctl = (sc520_mmcr->drcctl & 0xcf) | (val<<4);
 120
 121        val = sc520_mmcr->drctmctl & 0xf0;
 122
 123        if (cas_precharge_delay==3) {
 124                val |= 0x04;   /* 3T */
 125        } else if (cas_precharge_delay==4) {
 126                val |= 0x08;   /* 4T */
 127        } else if (cas_precharge_delay>4) {
 128                val |= 0x0c;
 129        }
 130
 131        if (ras_cas_delay > 3) {
 132                val |= 2;
 133        } else {
 134                val |= 1;
 135        }
 136        sc520_mmcr->drctmctl = val;
 137#endif
 138
 139        /* We read-back the configuration of the dram
 140         * controller that the assembly code wrote */
 141        dram_ctrl = sc520_mmcr->drcbendadr;
 142
 143        bd->bi_dram[0].start = 0;
 144        if (dram_ctrl & 0x80) {
 145                /* bank 0 enabled */
 146                dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
 147                bd->bi_dram[0].size = bd->bi_dram[1].start;
 148
 149        } else {
 150                bd->bi_dram[0].size = 0;
 151                bd->bi_dram[1].start = bd->bi_dram[0].start;
 152        }
 153
 154        if (dram_ctrl & 0x8000) {
 155                /* bank 1 enabled */
 156                dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
 157                bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start;
 158        } else {
 159                bd->bi_dram[1].size = 0;
 160                bd->bi_dram[2].start = bd->bi_dram[1].start;
 161        }
 162
 163        if (dram_ctrl & 0x800000) {
 164                /* bank 2 enabled */
 165                dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
 166                bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start;
 167        } else {
 168                bd->bi_dram[2].size = 0;
 169                bd->bi_dram[3].start = bd->bi_dram[2].start;
 170        }
 171
 172        if (dram_ctrl & 0x80000000) {
 173                /* bank 3 enabled */
 174                dram_present  = (dram_ctrl & 0x7f000000) >> 2;
 175                bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
 176        } else {
 177                bd->bi_dram[3].size = 0;
 178        }
 179
 180
 181#if 0
 182        printf("Configured %d bytes of dram\n", dram_present);
 183#endif
 184        gd->ram_size = dram_present;
 185
 186        return dram_present;
 187}
 188
 189#ifdef CONFIG_SYS_SC520_RESET
 190void reset_cpu(ulong addr)
 191{
 192        printf("Resetting using SC520 MMCR\n");
 193        /* Write a '1' to the SYS_RST of the RESCFG MMCR */
 194        sc520_mmcr->rescfg = 0x01;
 195
 196        /* NOTREACHED */
 197}
 198#endif
 199