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